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