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