varnish-cache/bin/varnishtest/vtest2/src/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 = VTAILQ_HEAD_INITIALIZER(servers);
72
73
/**********************************************************************
74
 * Allocate and initialize a server
75
 */
76
77 42769
static struct server *
78
server_new(const char *name, struct vtclog *vl)
79
{
80
        struct server *s;
81 42769
82 42769
        VTC_CHECK_NAME(vl, name, "Server", 's');
83 42769
        ALLOC_OBJ(s, SERVER_MAGIC);
84 42769
        AN(s);
85 42769
        REPLACE(s->name, name);
86 42769
        s->vl = vtc_logopen("%s", s->name);
87 42769
        AN(s->vl);
88 42769
        s->vsp = Sess_New(s->vl, name);
89
        AN(s->vsp);
90 42769
91 42769
        bprintf(s->listen, "%s", default_listen_addr);
92 42769
        s->depth = 10;
93 42769
        s->sock = -1;
94 42769
        s->fd = -1;
95 42769
        PTOK(pthread_mutex_lock(&server_mtx));
96 42769
        VTAILQ_INSERT_TAIL(&servers, s, list);
97 42769
        PTOK(pthread_mutex_unlock(&server_mtx));
98
        return (s);
99
}
100
101
/**********************************************************************
102
 * Clean up a server
103
 */
104
105 42769
static void
106
server_delete(struct server *s)
107
{
108 42769
109 42769
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
110 42769
        Sess_Destroy(&s->vsp);
111 42769
        macro_undef(s->vl, s->name, "addr");
112 42769
        macro_undef(s->vl, s->name, "port");
113 42769
        macro_undef(s->vl, s->name, "sock");
114 42769
        vtc_logclose(s->vl);
115
        free(s->name);
116 42769
        /* XXX: MEMLEAK (?) (VSS ??) */
117 42769
        FREE_OBJ(s);
118
}
119
120
/**********************************************************************
121
 * Server listen
122
 */
123
124
struct helper {
125
        int             depth;
126
        const char      **errp;
127
};
128
129
/* cf. VTCP_listen_on() */
130 2080
static int v_matchproto_(vus_resolved_f)
131
uds_listen(void *priv, const struct sockaddr_un *uds)
132
{
133 2080
        int sock, e;
134
        struct helper *hp = priv;
135 2080
136 2080
        sock = VUS_bind(uds, hp->errp);
137 2080
        if (sock >= 0)   {
138 0
                if (listen(sock, hp->depth) != 0) {
139 0
                        e = errno;
140 0
                        closefd(&sock);
141 0
                        errno = e;
142 0
                        if (hp->errp != NULL)
143 0
                                *hp->errp = "listen(2)";
144
                        return (-1);
145 2080
                }
146 2080
        }
147 2080
        if (sock > 0) {
148 2080
                *hp->errp = NULL;
149
                return (sock);
150 0
        }
151 0
        AN(*hp->errp);
152 2080
        return (0);
153
}
154
155 2080
static void
156
server_listen_uds(struct server *s, const char **errp)
157
{
158
        mode_t m;
159
        struct helper h;
160 2080
161 2080
        h.depth = s->depth;
162
        h.errp = errp;
163 2080
164 2080
        errno = 0;
165 0
        if (unlink(s->listen) != 0 && errno != ENOENT)
166 0
                vtc_fatal(s->vl, "Could not unlink %s before bind: %s",
167
                    s->listen, strerror(errno));
168
        /*
169
         * Temporarily set the umask to 0 to avoid issues with
170
         * permissions.
171 2080
         */
172 2080
        m = umask(0);
173 2080
        s->sock = VUS_resolver(s->listen, uds_listen, &h, errp);
174 2080
        (void)umask(m);
175 0
        if (*errp != NULL)
176 2080
                return;
177 2080
        assert(s->sock > 0);
178 2080
        macro_def(s->vl, s->name, "addr", "0.0.0.0");
179 2080
        macro_def(s->vl, s->name, "port", "0");
180 2080
        macro_def(s->vl, s->name, "sock", "%s", s->listen);
181
}
182
183 42040
static void
184
server_listen_tcp(struct server *s, const char **errp)
185 42040
{
186
        char buf[vsa_suckaddr_len];
187
        const struct suckaddr *sua;
188 42040
189 42040
        s->sock = VTCP_listen_on(s->listen, "0", s->depth, errp);
190 0
        if (*errp != NULL)
191 42040
                return;
192 42040
        assert(s->sock > 0);
193 42040
        sua = VSA_getsockname(s->sock, buf, sizeof buf);
194 84080
        AN(sua);
195 42040
        VTCP_name(sua, s->aaddr, sizeof s->aaddr,
196
            s->aport, sizeof s->aport);
197
198 42040
        /* Record the actual port, and reuse it on subsequent starts */
199 41880
        if (VSA_Get_Proto(sua) == AF_INET)
200
                bprintf(s->listen, "%s:%s", s->aaddr, s->aport);
201 160
        else
202
                bprintf(s->listen, "[%s]:%s", s->aaddr, s->aport);
203 42040
204 42040
        macro_def(s->vl, s->name, "addr", "%s", s->aaddr);
205 42040
        macro_def(s->vl, s->name, "port", "%s", s->aport);
206 42040
        macro_def(s->vl, s->name, "sock", "%s", s->listen);
207
}
208
209 44120
static void
210
server_listen(struct server *s)
211
{
212
        const char *err;
213 44120
214
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
215 44120
216 3880
        if (s->sock >= 0)
217 44120
                VTCP_close(&s->sock);
218 2080
        if (VUS_is(s->listen))
219
                server_listen_uds(s, &err);
220 42040
        else
221 44120
                server_listen_tcp(s, &err);
222 0
        if (err != NULL)
223
                vtc_fatal(s->vl,
224 0
                    "Server listen address (%s) cannot be resolved: %s",
225 44120
                    s->listen, err);
226
}
227
228
/**********************************************************************
229
 * Server thread
230
 */
231
232 54788
static int
233
server_conn(void *priv, struct vtclog *vl)
234
{
235
        struct server *s;
236
        struct sockaddr_storage addr_s;
237
        struct sockaddr *addr;
238
        char abuf[VTCP_ADDRBUFSIZE];
239
        char pbuf[VTCP_PORTBUFSIZE];
240
        socklen_t l;
241
        int fd;
242 54788
243
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
244 54788
245 54788
        addr = (void*)&addr_s;
246 54788
        l = sizeof addr_s;
247 54788
        fd = accept(s->sock, addr, &l);
248 0
        if (fd < 0)
249 54788
                vtc_fatal(vl, "Accept failed: %s", strerror(errno));
250 2040
        if (VUS_is(s->listen))
251
                vtc_log(vl, 3, "accepted fd %d 0.0.0.0 0", fd);
252 52748
        else {
253 52748
                VTCP_hisname(fd, abuf, sizeof abuf, pbuf, sizeof pbuf);
254
                vtc_log(vl, 3, "accepted fd %d %s %s", fd, abuf, pbuf);
255 54788
        }
256
        return (fd);
257
}
258
259 53627
static void
260
server_disc(void *priv, struct vtclog *vl, int *fdp)
261
{
262
        int j;
263
        struct server *s;
264 53627
265 53627
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
266 53627
        vtc_log(vl, 3, "shutting fd %d (server run)", *fdp);
267 53627
        j = shutdown(*fdp, SHUT_WR);
268 0
        if (!vtc_stop && !VTCP_Check(j))
269 53631
                vtc_fatal(vl, "Shutdown failed: %s", strerror(errno));
270 53631
        VTCP_close(fdp);
271
}
272
273 43560
static void
274
server_start_thread(struct server *s)
275
{
276 43560
277 43560
        s->run = 1;
278 43560
        s->tp = Sess_Start_Thread(
279 43560
            s,
280
            s->vsp,
281
            server_conn,
282 43560
            server_disc,
283 43560
            s->listen,
284 43560
            &s->sock,
285
            s->spec
286 43560
        );
287
}
288
289
/**********************************************************************
290
 * Start the server thread
291
 */
292
293 43560
static void
294
server_start(struct server *s)
295 43560
{
296 43560
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
297 43560
        vtc_log(s->vl, 2, "Starting server");
298 43560
        server_listen(s);
299 43560
        vtc_log(s->vl, 1, "Listen on %s", s->listen);
300 43560
        server_start_thread(s);
301
}
302
303
/**********************************************************************
304
 */
305
306 2769
static void *
307
server_dispatch_wrk(void *priv)
308
{
309
        struct server *s;
310
        struct vtclog *vl;
311
        int j, fd;
312 2769
313 2769
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
314
        assert(s->sock < 0);
315 2769
316 2769
        vl = vtc_logopen("%s", s->name);
317
        pthread_cleanup_push(vtc_logclose, vl);
318 2769
319
        fd = s->fd;
320 2769
321 2769
        vtc_log(vl, 3, "start with fd %d", fd);
322 2769
        fd = sess_process(vl, s->vsp, s->spec, fd, &s->sock, s->listen);
323 2769
        vtc_log(vl, 3, "shutting fd %d (server dispatch)", fd);
324 2769
        j = shutdown(fd, SHUT_WR);
325 0
        if (!VTCP_Check(j))
326 2769
                vtc_fatal(vl, "Shutdown failed: %s", strerror(errno));
327 2769
        VTCP_close(&s->fd);
328 2769
        vtc_log(vl, 2, "Ending");
329 2769
        pthread_cleanup_pop(0);
330 2769
        vtc_logclose(vl);
331
        return (NULL);
332
}
333
334 560
static void *
335
server_dispatch_thread(void *priv)
336
{
337
        struct server *s, *s2;
338
        static int sn = 1;
339
        int fd;
340
        char snbuf[8];
341
        struct vtclog *vl;
342
        struct sockaddr_storage addr_s;
343
        struct sockaddr *addr;
344
        socklen_t l;
345 560
346 560
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
347
        assert(s->sock >= 0);
348 560
349 560
        vl = vtc_logopen("%s", s->name);
350
        pthread_cleanup_push(vtc_logclose, vl);
351 560
352
        vtc_log(vl, 2, "Dispatch started on %s", s->listen);
353 3329
354 2769
        while (!vtc_stop) {
355 2769
                addr = (void*)&addr_s;
356 2769
                l = sizeof addr_s;
357 2769
                fd = accept(s->sock, addr, &l);
358 0
                if (fd < 0)
359 2769
                        vtc_fatal(vl, "Accepted failed: %s", strerror(errno));
360 2769
                bprintf(snbuf, "s%d", sn++);
361 2769
                vtc_log(vl, 3, "dispatch fd %d -> %s", fd, snbuf);
362 2769
                s2 = server_new(snbuf, vl);
363 2769
                s2->is_dispatch = 1;
364 2769
                s2->spec = s->spec;
365 2769
                bstrcpy(s2->listen, s->listen);
366 2769
                s2->fd = fd;
367 2769
                s2->run = 1;
368
                PTOK(pthread_create(&s2->tp, NULL, server_dispatch_wrk, s2));
369 560
        }
370 560
        pthread_cleanup_pop(0);
371 560
        vtc_logclose(vl);
372
        NEEDLESS(return (NULL));
373
}
374
375 560
static void
376
server_dispatch(struct server *s)
377 560
{
378 560
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
379 560
        server_listen(s);
380 560
        vtc_log(s->vl, 2, "Starting dispatch server");
381 560
        s->run = 1;
382 560
        PTOK(pthread_create(&s->tp, NULL, server_dispatch_thread, s));
383
}
384
385
/**********************************************************************
386
 * Force stop the server thread
387
 */
388
389 240
static void
390
server_break(struct server *s)
391
{
392
        void *res;
393 240
394 240
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
395 240
        vtc_log(s->vl, 2, "Breaking for server");
396 240
        (void)pthread_cancel(s->tp);
397 240
        PTOK(pthread_join(s->tp, &res));
398 240
        VTCP_close(&s->sock);
399 240
        s->tp = 0;
400 240
        s->run = 0;
401
}
402
403
/**********************************************************************
404
 * Wait for server thread to stop
405
 */
406
407 46649
static void
408
server_wait(struct server *s)
409
{
410
        void *res;
411 46649
412 46649
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
413 46649
        vtc_log(s->vl, 2, "Waiting for server (%d/%d)", s->sock, s->fd);
414 46649
        PTOK(pthread_join(s->tp, &res));
415 0
        if (res != NULL && !vtc_stop)
416 0
                vtc_fatal(s->vl, "Server returned \"%p\"",
417 46649
                    (char *)res);
418 46649
        s->tp = 0;
419 46649
        s->run = 0;
420
}
421
422
/**********************************************************************
423
 * Generate VCL backend decls for our servers
424
 */
425
426 36160
void
427
cmd_server_gen_vcl(struct vsb *vsb)
428
{
429
        struct server *s;
430 36160
431 77202
        PTOK(pthread_mutex_lock(&server_mtx));
432 41042
        VTAILQ_FOREACH(s, &servers, list) {
433 802
                if (s->is_dispatch)
434
                        continue;
435 40240
436 1360
                if (VUS_is(s->listen))
437
                        VSB_printf(vsb,
438 680
                           "backend %s { .path = \"%s\"; }\n",
439
                           s->name, s->listen);
440 79120
                else
441
                        VSB_printf(vsb,
442 39560
                           "backend %s { .host = \"%s\"; .port = \"%s\"; }\n",
443 40240
                           s->name, s->aaddr, s->aport);
444 36160
        }
445 36160
        PTOK(pthread_mutex_unlock(&server_mtx));
446
}
447
448
449
/**********************************************************************
450
 * Generate VCL backend decls for our servers
451
 */
452
453 40
void
454
cmd_server_gen_haproxy_conf(struct vsb *vsb)
455
{
456
        struct server *s;
457 40
458 80
        PTOK(pthread_mutex_lock(&server_mtx));
459 40
        VTAILQ_FOREACH(s, &servers, list) {
460 80
                if (! VUS_is(s->listen))
461
                        VSB_printf(vsb,
462
                           "\n    backend be%s\n"
463 40
                           "\tserver srv%s %s:%s\n",
464
                           s->name + 1, s->name + 1, s->aaddr, s->aport);
465 0
                else
466 40
                        INCOMPL();
467 80
        }
468 40
        VTAILQ_FOREACH(s, &servers, list) {
469 80
                if (! VUS_is(s->listen))
470
                        VSB_printf(vsb,
471
                           "\n    frontend http%s\n"
472
                           "\tuse_backend be%s\n"
473 40
                           "\tbind \"fd@${fe%s}\"\n",
474
                           s->name + 1, s->name + 1, s->name + 1);
475 0
                else
476 40
                        INCOMPL();
477 40
        }
478 40
        PTOK(pthread_mutex_unlock(&server_mtx));
479
}
480
481
482
/**********************************************************************
483
 * Server command dispatch
484
 */
485
486 90400
void
487
cmd_server(CMD_ARGS)
488
{
489
        struct server *s;
490 90400
491
        (void)priv;
492 90400
493
        if (av == NULL) {
494 84169
                /* Reset and free */
495 84169
                while (1) {
496 84169
                        PTOK(pthread_mutex_lock(&server_mtx));
497 84169
                        s = VTAILQ_FIRST(&servers);
498 84169
                        CHECK_OBJ_ORNULL(s, SERVER_MAGIC);
499 42769
                        if (s != NULL)
500 84169
                                VTAILQ_REMOVE(&servers, s, list);
501 84169
                        PTOK(pthread_mutex_unlock(&server_mtx));
502 41400
                        if (s == NULL)
503 42769
                                break;
504 39729
                        if (s->run) {
505 39729
                                (void)pthread_cancel(s->tp);
506 39729
                                server_wait(s);
507 42769
                        }
508 40000
                        if (s->sock >= 0)
509 42769
                                VTCP_close(&s->sock);
510
                        server_delete(s);
511 41400
                }
512
                return;
513
        }
514 49000
515 49000
        AZ(strcmp(av[0], "server"));
516
        av++;
517 49000
518 59560
        PTOK(pthread_mutex_lock(&server_mtx));
519 19560
        VTAILQ_FOREACH(s, &servers, list)
520 9000
                if (!strcmp(s->name, av[0]))
521 49000
                        break;
522 49000
        PTOK(pthread_mutex_unlock(&server_mtx));
523 40000
        if (s == NULL)
524 49000
                s = server_new(av[0], vl);
525 49000
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
526
        av++;
527 145840
528 96840
        for (; *av != NULL; av++) {
529 0
                if (vtc_error)
530 96840
                        break;
531 4080
                if (!strcmp(*av, "-wait")) {
532 0
                        if (!s->run)
533 4080
                                vtc_fatal(s->vl, "Server not -started");
534 4080
                        server_wait(s);
535
                        continue;
536
                }
537 92760
538 240
                if (!strcmp(*av, "-break")) {
539 240
                        server_break(s);
540
                        continue;
541
                }
542
543
                /*
544
                 * We do an implicit -wait if people muck about with a
545
                 * running server.
546 92520
                 */
547 2840
                if (s->run)
548
                        server_wait(s);
549 92520
550
                AZ(s->run);
551 92520
552 3240
                if (Sess_GetOpt(s->vsp, &av))
553
                        continue;
554 89280
555 2080
                if (!strcmp(*av, "-listen")) {
556 0
                        if (s->sock >= 0)
557 2080
                                VTCP_close(&s->sock);
558 2080
                        bprintf(s->listen, "%s", av[1]);
559 2080
                        av++;
560
                        continue;
561 87200
                }
562 43560
                if (!strcmp(*av, "-start")) {
563 43560
                        server_start(s);
564
                        continue;
565 43640
                }
566 560
                if (!strcmp(*av, "-dispatch")) {
567 0
                        if (strcmp(s->name, "s0"))
568
                                vtc_fatal(s->vl,
569 560
                                    "server -dispatch only works on s0");
570 560
                        server_dispatch(s);
571
                        continue;
572 43080
                }
573 0
                if (**av == '-')
574 43080
                        vtc_fatal(s->vl, "Unknown server argument: %s", *av);
575 43080
                s->spec = *av;
576 90400
        }
577
}
578
579 41400
void
580
init_server(void)
581 41400
{
582 41400
        PTOK(pthread_mutex_init(&server_mtx, NULL));
583
}