varnish-cache/bin/varnishtest/vtc_server.c
0
/*-
1
 * Copyright (c) 2008-2010 Varnish Software AS
2
 * All rights reserved.
3
 *
4
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
5
 *
6
 * SPDX-License-Identifier: BSD-2-Clause
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
30
#include "config.h"
31
32
#include <sys/socket.h>
33
#include <sys/types.h>
34
#include <sys/stat.h>
35
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
#include <unistd.h>
40
41
#include "vsa.h"
42
#include "vtc.h"
43
44
#include "vtcp.h"
45
#include "vus.h"
46
47
struct server {
48
        unsigned                magic;
49
#define SERVER_MAGIC            0x55286619
50
        char                    *name;
51
        struct vtclog           *vl;
52
        VTAILQ_ENTRY(server)    list;
53
        struct vtc_sess         *vsp;
54
        char                    run;
55
56
        char                    *spec;
57
58
        int                     depth;
59
        int                     sock;
60
        int                     fd;
61
        unsigned                is_dispatch;
62
        char                    listen[256];
63
        char                    aaddr[VTCP_ADDRBUFSIZE];
64
        char                    aport[VTCP_PORTBUFSIZE];
65
66
        pthread_t               tp;
67
};
68
69
static pthread_mutex_t          server_mtx;
70
71
static VTAILQ_HEAD(, server)    servers =
72
    VTAILQ_HEAD_INITIALIZER(servers);
73
74
/**********************************************************************
75
 * Allocate and initialize a server
76
 */
77
78
static struct server *
79 41541
server_new(const char *name, struct vtclog *vl)
80
{
81
        struct server *s;
82
83 41541
        VTC_CHECK_NAME(vl, name, "Server", 's');
84 41541
        ALLOC_OBJ(s, SERVER_MAGIC);
85 41541
        AN(s);
86 41541
        REPLACE(s->name, name);
87 41541
        s->vl = vtc_logopen("%s", s->name);
88 41541
        AN(s->vl);
89 41541
        s->vsp = Sess_New(s->vl, name);
90 41541
        AN(s->vsp);
91
92 41541
        bprintf(s->listen, "%s", default_listen_addr);
93 41541
        s->depth = 10;
94 41541
        s->sock = -1;
95 41541
        s->fd = -1;
96 41541
        PTOK(pthread_mutex_lock(&server_mtx));
97 41541
        VTAILQ_INSERT_TAIL(&servers, s, list);
98 41541
        PTOK(pthread_mutex_unlock(&server_mtx));
99 41541
        return (s);
100
}
101
102
/**********************************************************************
103
 * Clean up a server
104
 */
105
106
static void
107 41541
server_delete(struct server *s)
108
{
109
110 41541
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
111 41541
        Sess_Destroy(&s->vsp);
112 41541
        macro_undef(s->vl, s->name, "addr");
113 41541
        macro_undef(s->vl, s->name, "port");
114 41541
        macro_undef(s->vl, s->name, "sock");
115 41541
        vtc_logclose(s->vl);
116 41541
        free(s->name);
117
        /* XXX: MEMLEAK (?) (VSS ??) */
118 41541
        FREE_OBJ(s);
119 41541
}
120
121
/**********************************************************************
122
 * Server listen
123
 */
124
125
struct helper {
126
        int             depth;
127
        const char      **errp;
128
};
129
130
/* cf. VTCP_listen_on() */
131
static int v_matchproto_(vus_resolved_f)
132 2360
uds_listen(void *priv, const struct sockaddr_un *uds)
133
{
134
        int sock, e;
135 2360
        struct helper *hp = priv;
136
137 2360
        sock = VUS_bind(uds, hp->errp);
138 2360
        if (sock >= 0)   {
139 2360
                if (listen(sock, hp->depth) != 0) {
140 0
                        e = errno;
141 0
                        closefd(&sock);
142 0
                        errno = e;
143 0
                        if (hp->errp != NULL)
144 0
                                *hp->errp = "listen(2)";
145 0
                        return (-1);
146
                }
147 2360
        }
148 2360
        if (sock > 0) {
149 2360
                *hp->errp = NULL;
150 2360
                return (sock);
151
        }
152 0
        AN(*hp->errp);
153 0
        return (0);
154 2360
}
155
156
static void
157 2360
server_listen_uds(struct server *s, const char **errp)
158
{
159
        mode_t m;
160
        struct helper h;
161
162 2360
        h.depth = s->depth;
163 2360
        h.errp = errp;
164
165 2360
        errno = 0;
166 2360
        if (unlink(s->listen) != 0 && errno != ENOENT)
167 0
                vtc_fatal(s->vl, "Could not unlink %s before bind: %s",
168 0
                    s->listen, strerror(errno));
169
        /*
170
         * Temporarily set the umask to 0 to avoid issues with
171
         * permissions.
172
         */
173 2360
        m = umask(0);
174 2360
        s->sock = VUS_resolver(s->listen, uds_listen, &h, errp);
175 2360
        (void)umask(m);
176 2360
        if (*errp != NULL)
177 0
                return;
178 2360
        assert(s->sock > 0);
179 2360
        macro_def(s->vl, s->name, "addr", "0.0.0.0");
180 2360
        macro_def(s->vl, s->name, "port", "0");
181 2360
        macro_def(s->vl, s->name, "sock", "%s", s->listen);
182 2360
}
183
184
static void
185 40240
server_listen_tcp(struct server *s, const char **errp)
186
{
187 40240
        char buf[vsa_suckaddr_len];
188
        const struct suckaddr *sua;
189
190 40240
        s->sock = VTCP_listen_on(s->listen, "0", s->depth, errp);
191 40240
        if (*errp != NULL)
192 0
                return;
193 40240
        assert(s->sock > 0);
194 40240
        sua = VSA_getsockname(s->sock, buf, sizeof buf);
195 40240
        AN(sua);
196 80480
        VTCP_name(sua, s->aaddr, sizeof s->aaddr,
197 40240
            s->aport, sizeof s->aport);
198
199
        /* Record the actual port, and reuse it on subsequent starts */
200 40240
        if (VSA_Get_Proto(sua) == AF_INET)
201 40080
                bprintf(s->listen, "%s:%s", s->aaddr, s->aport);
202
        else
203 160
                bprintf(s->listen, "[%s]:%s", s->aaddr, s->aport);
204
205 40240
        macro_def(s->vl, s->name, "addr", "%s", s->aaddr);
206 40240
        macro_def(s->vl, s->name, "port", "%s", s->aport);
207 40240
        macro_def(s->vl, s->name, "sock", "%s", s->listen);
208 40240
}
209
210
static void
211 42600
server_listen(struct server *s)
212
{
213
        const char *err;
214
215 42600
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
216
217 42600
        if (s->sock >= 0)
218 3560
                VTCP_close(&s->sock);
219 42600
        if (VUS_is(s->listen))
220 2360
                server_listen_uds(s, &err);
221
        else
222 40240
                server_listen_tcp(s, &err);
223 42600
        if (err != NULL)
224 0
                vtc_fatal(s->vl,
225
                    "Server listen address (%s) cannot be resolved: %s",
226 0
                    s->listen, err);
227 42600
}
228
229
/**********************************************************************
230
 * Server thread
231
 */
232
233
static int
234 53330
server_conn(void *priv, struct vtclog *vl)
235
{
236
        struct server *s;
237
        struct sockaddr_storage addr_s;
238
        struct sockaddr *addr;
239
        char abuf[VTCP_ADDRBUFSIZE];
240
        char pbuf[VTCP_PORTBUFSIZE];
241
        socklen_t l;
242
        int fd;
243
244 53330
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
245
246 53330
        addr = (void*)&addr_s;
247 53330
        l = sizeof addr_s;
248 53330
        fd = accept(s->sock, addr, &l);
249 53330
        if (fd < 0)
250 0
                vtc_fatal(vl, "Accept failed: %s", strerror(errno));
251 53330
        if (VUS_is(s->listen))
252 2360
                vtc_log(vl, 3, "accepted fd %d 0.0.0.0 0", fd);
253
        else {
254 50970
                VTCP_hisname(fd, abuf, sizeof abuf, pbuf, sizeof pbuf);
255 50970
                vtc_log(vl, 3, "accepted fd %d %s %s", fd, abuf, pbuf);
256
        }
257 53330
        return (fd);
258
}
259
260
static void
261 52367
server_disc(void *priv, struct vtclog *vl, int *fdp)
262
{
263
        int j;
264
        struct server *s;
265
266 52367
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
267 52367
        vtc_log(vl, 3, "shutting fd %d", *fdp);
268 52367
        j = shutdown(*fdp, SHUT_WR);
269 52367
        if (!vtc_stop && !VTCP_Check(j))
270 0
                vtc_fatal(vl, "Shutdown failed: %s", strerror(errno));
271 52373
        VTCP_close(fdp);
272 52373
}
273
274
static void
275 42080
server_start_thread(struct server *s)
276
{
277
278 42080
        s->run = 1;
279 42080
        s->tp = Sess_Start_Thread(
280 42080
            s,
281 42080
            s->vsp,
282
            server_conn,
283
            server_disc,
284 42080
            s->listen,
285 42080
            &s->sock,
286 42080
            s->spec
287
        );
288 42080
}
289
290
/**********************************************************************
291
 * Start the server thread
292
 */
293
294
static void
295 42080
server_start(struct server *s)
296
{
297 42080
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
298 42080
        vtc_log(s->vl, 2, "Starting server");
299 42080
        server_listen(s);
300 42080
        vtc_log(s->vl, 1, "Listen on %s", s->listen);
301 42080
        server_start_thread(s);
302 42080
}
303
304
/**********************************************************************
305
 */
306
307
static void *
308 2621
server_dispatch_wrk(void *priv)
309
{
310
        struct server *s;
311
        struct vtclog *vl;
312
        int j, fd;
313
314 2621
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
315 2621
        assert(s->sock < 0);
316
317 2621
        vl = vtc_logopen("%s", s->name);
318 2621
        pthread_cleanup_push(vtc_logclose, vl);
319
320 2621
        fd = s->fd;
321
322 2621
        vtc_log(vl, 3, "start with fd %d", fd);
323 2621
        fd = sess_process(vl, s->vsp, s->spec, fd, &s->sock, s->listen);
324 2621
        vtc_log(vl, 3, "shutting fd %d", fd);
325 2621
        j = shutdown(fd, SHUT_WR);
326 2621
        if (!VTCP_Check(j))
327 0
                vtc_fatal(vl, "Shutdown failed: %s", strerror(errno));
328 2621
        VTCP_close(&s->fd);
329 2621
        vtc_log(vl, 2, "Ending");
330 2621
        pthread_cleanup_pop(0);
331 2621
        vtc_logclose(vl);
332 2621
        return (NULL);
333
}
334
335
static void *
336 520
server_dispatch_thread(void *priv)
337
{
338
        struct server *s, *s2;
339
        static int sn = 1;
340
        int fd;
341
        char snbuf[8];
342
        struct vtclog *vl;
343
        struct sockaddr_storage addr_s;
344
        struct sockaddr *addr;
345
        socklen_t l;
346
347 520
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
348 520
        assert(s->sock >= 0);
349
350 520
        vl = vtc_logopen("%s", s->name);
351 520
        pthread_cleanup_push(vtc_logclose, vl);
352
353 520
        vtc_log(vl, 2, "Dispatch started on %s", s->listen);
354
355 3141
        while (!vtc_stop) {
356 2621
                addr = (void*)&addr_s;
357 2621
                l = sizeof addr_s;
358 2621
                fd = accept(s->sock, addr, &l);
359 2621
                if (fd < 0)
360 0
                        vtc_fatal(vl, "Accepted failed: %s", strerror(errno));
361 2621
                bprintf(snbuf, "s%d", sn++);
362 2621
                vtc_log(vl, 3, "dispatch fd %d -> %s", fd, snbuf);
363 2621
                s2 = server_new(snbuf, vl);
364 2621
                s2->is_dispatch = 1;
365 2621
                s2->spec = s->spec;
366 2621
                bstrcpy(s2->listen, s->listen);
367 2621
                s2->fd = fd;
368 2621
                s2->run = 1;
369 2621
                PTOK(pthread_create(&s2->tp, NULL, server_dispatch_wrk, s2));
370
        }
371 520
        pthread_cleanup_pop(0);
372 520
        vtc_logclose(vl);
373 520
        NEEDLESS(return (NULL));
374
}
375
376
static void
377 520
server_dispatch(struct server *s)
378
{
379 520
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
380 520
        server_listen(s);
381 520
        vtc_log(s->vl, 2, "Starting dispatch server");
382 520
        s->run = 1;
383 520
        PTOK(pthread_create(&s->tp, NULL, server_dispatch_thread, s));
384 520
}
385
386
/**********************************************************************
387
 * Force stop the server thread
388
 */
389
390
static void
391 120
server_break(struct server *s)
392
{
393
        void *res;
394
395 120
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
396 120
        vtc_log(s->vl, 2, "Breaking for server");
397 120
        (void)pthread_cancel(s->tp);
398 120
        PTOK(pthread_join(s->tp, &res));
399 120
        VTCP_close(&s->sock);
400 120
        s->tp = 0;
401 120
        s->run = 0;
402 120
}
403
404
/**********************************************************************
405
 * Wait for server thread to stop
406
 */
407
408
static void
409 45101
server_wait(struct server *s)
410
{
411
        void *res;
412
413 45101
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
414 45101
        vtc_log(s->vl, 2, "Waiting for server (%d/%d)", s->sock, s->fd);
415 45101
        PTOK(pthread_join(s->tp, &res));
416 45101
        if (res != NULL && !vtc_stop)
417 0
                vtc_fatal(s->vl, "Server returned \"%p\"",
418 0
                    (char *)res);
419 45101
        s->tp = 0;
420 45101
        s->run = 0;
421 45101
}
422
423
/**********************************************************************
424
 * Generate VCL backend decls for our servers
425
 */
426
427
void
428 34000
cmd_server_gen_vcl(struct vsb *vsb)
429
{
430
        struct server *s;
431
432 34000
        PTOK(pthread_mutex_lock(&server_mtx));
433 72720
        VTAILQ_FOREACH(s, &servers, list) {
434 38720
                if (s->is_dispatch)
435 640
                        continue;
436
437 38080
                if (VUS_is(s->listen))
438 1360
                        VSB_printf(vsb,
439
                           "backend %s { .path = \"%s\"; }\n",
440 680
                           s->name, s->listen);
441
                else
442 74800
                        VSB_printf(vsb,
443
                           "backend %s { .host = \"%s\"; .port = \"%s\"; }\n",
444 37400
                           s->name, s->aaddr, s->aport);
445 38080
        }
446 34000
        PTOK(pthread_mutex_unlock(&server_mtx));
447 34000
}
448
449
450
/**********************************************************************
451
 * Generate VCL backend decls for our servers
452
 */
453
454
void
455 40
cmd_server_gen_haproxy_conf(struct vsb *vsb)
456
{
457
        struct server *s;
458
459 40
        PTOK(pthread_mutex_lock(&server_mtx));
460 80
        VTAILQ_FOREACH(s, &servers, list) {
461 40
                if (! VUS_is(s->listen))
462 80
                        VSB_printf(vsb,
463
                           "\n    backend be%s\n"
464
                           "\tserver srv%s %s:%s\n",
465 40
                           s->name + 1, s->name + 1, s->aaddr, s->aport);
466
                else
467 0
                        INCOMPL();
468 40
        }
469 80
        VTAILQ_FOREACH(s, &servers, list) {
470 40
                if (! VUS_is(s->listen))
471 80
                        VSB_printf(vsb,
472
                           "\n    frontend http%s\n"
473
                           "\tuse_backend be%s\n"
474
                           "\tbind \"fd@${fe%s}\"\n",
475 40
                           s->name + 1, s->name + 1, s->name + 1);
476
                else
477 0
                        INCOMPL();
478 40
        }
479 40
        PTOK(pthread_mutex_unlock(&server_mtx));
480 40
}
481
482
483
/**********************************************************************
484
 * Server command dispatch
485
 */
486
487
void
488 87560
cmd_server(CMD_ARGS)
489
{
490
        struct server *s;
491
492 87560
        (void)priv;
493
494 87560
        if (av == NULL) {
495
                /* Reset and free */
496 81181
                while (1) {
497 81181
                        PTOK(pthread_mutex_lock(&server_mtx));
498 81181
                        s = VTAILQ_FIRST(&servers);
499 81181
                        CHECK_OBJ_ORNULL(s, SERVER_MAGIC);
500 81181
                        if (s != NULL)
501 41541
                                VTAILQ_REMOVE(&servers, s, list);
502 81181
                        PTOK(pthread_mutex_unlock(&server_mtx));
503 81181
                        if (s == NULL)
504 39640
                                break;
505 41541
                        if (s->run) {
506 38381
                                (void)pthread_cancel(s->tp);
507 38381
                                server_wait(s);
508 38381
                        }
509 41541
                        if (s->sock >= 0)
510 38920
                                VTCP_close(&s->sock);
511 41541
                        server_delete(s);
512
                }
513 39640
                return;
514
        }
515
516 47920
        AZ(strcmp(av[0], "server"));
517 47920
        av++;
518
519 47920
        PTOK(pthread_mutex_lock(&server_mtx));
520 60200
        VTAILQ_FOREACH(s, &servers, list)
521 21280
                if (!strcmp(s->name, av[0]))
522 9000
                        break;
523 47920
        PTOK(pthread_mutex_unlock(&server_mtx));
524 47920
        if (s == NULL)
525 38920
                s = server_new(av[0], vl);
526 47920
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
527 47920
        av++;
528
529 141960
        for (; *av != NULL; av++) {
530 94040
                if (vtc_error)
531 0
                        break;
532 94040
                if (!strcmp(*av, "-wait")) {
533 4080
                        if (!s->run)
534 0
                                vtc_fatal(s->vl, "Server not -started");
535 4080
                        server_wait(s);
536 4080
                        continue;
537
                }
538
539 89960
                if (!strcmp(*av, "-break")) {
540 120
                        server_break(s);
541 120
                        continue;
542
                }
543
544
                /*
545
                 * We do an implict -wait if people muck about with a
546
                 * running server.
547
                 */
548 89840
                if (s->run)
549 2640
                        server_wait(s);
550
551 89840
                AZ(s->run);
552
553 89840
                if (Sess_GetOpt(s->vsp, &av))
554 3160
                        continue;
555
556 86680
                if (!strcmp(*av, "-listen")) {
557 2360
                        if (s->sock >= 0)
558 0
                                VTCP_close(&s->sock);
559 2360
                        bprintf(s->listen, "%s", av[1]);
560 2360
                        av++;
561 2360
                        continue;
562
                }
563 84320
                if (!strcmp(*av, "-start")) {
564 42080
                        server_start(s);
565 42080
                        continue;
566
                }
567 42240
                if (!strcmp(*av, "-dispatch")) {
568 520
                        if (strcmp(s->name, "s0"))
569 0
                                vtc_fatal(s->vl,
570
                                    "server -dispatch only works on s0");
571 520
                        server_dispatch(s);
572 520
                        continue;
573
                }
574 41720
                if (**av == '-')
575 0
                        vtc_fatal(s->vl, "Unknown server argument: %s", *av);
576 41720
                s->spec = *av;
577 41720
        }
578 87560
}
579
580
void
581 39640
init_server(void)
582
{
583 39640
        PTOK(pthread_mutex_init(&server_mtx, NULL));
584 39640
}