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 12755
server_new(const char *name, struct vtclog *vl)
79
{
80
        struct server *s;
81
82 12755
        VTC_CHECK_NAME(vl, name, "Server", 's');
83 12755
        ALLOC_OBJ(s, SERVER_MAGIC);
84 12755
        AN(s);
85 12755
        REPLACE(s->name, name);
86 12755
        s->vl = vtc_logopen(s->name);
87 12755
        AN(s->vl);
88
89 12755
        bprintf(s->listen, "%s", "127.0.0.1 0");
90 12755
        s->repeat = 1;
91 12755
        s->depth = 10;
92 12755
        s->sock = -1;
93 12755
        s->fd = -1;
94 12755
        AZ(pthread_mutex_lock(&server_mtx));
95 12755
        VTAILQ_INSERT_TAIL(&servers, s, list);
96 12755
        AZ(pthread_mutex_unlock(&server_mtx));
97 12755
        return (s);
98
}
99
100
/**********************************************************************
101
 * Clean up a server
102
 */
103
104
static void
105 12755
server_delete(struct server *s)
106
{
107
108 12755
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
109 12755
        macro_undef(s->vl, s->name, "addr");
110 12755
        macro_undef(s->vl, s->name, "port");
111 12755
        macro_undef(s->vl, s->name, "sock");
112 12755
        vtc_logclose(s->vl);
113 12755
        free(s->name);
114
        /* XXX: MEMLEAK (?) (VSS ??) */
115 12755
        FREE_OBJ(s);
116 12755
}
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 885
uds_listen(void *priv, const struct sockaddr_un *uds)
130
{
131
        int sock, e;
132 885
        struct helper *hp = priv;
133
134 885
        sock = VUS_bind(uds, hp->errp);
135 885
        if (sock >= 0)   {
136 885
                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 885
        }
145 885
        if (sock > 0) {
146 885
                *hp->errp = NULL;
147 885
                return (sock);
148
        }
149 0
        AN(*hp->errp);
150 0
        return (0);
151 885
}
152
153
static void
154 885
server_listen_uds(struct server *s, const char **errp)
155
{
156
        mode_t m;
157
        struct helper h;
158
159 885
        h.depth = s->depth;
160 885
        h.errp = errp;
161
162 885
        errno = 0;
163 885
        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 885
        m = umask(0);
171 885
        s->sock = VUS_resolver(s->listen, uds_listen, &h, errp);
172 885
        (void)umask(m);
173 885
        if (*errp != NULL)
174 0
                return;
175 885
        assert(s->sock > 0);
176 885
        macro_def(s->vl, s->name, "addr", "0.0.0.0");
177 885
        macro_def(s->vl, s->name, "port", "0");
178 885
        macro_def(s->vl, s->name, "sock", "%s", s->listen);
179 885
}
180
181
static void
182 12810
server_listen_tcp(struct server *s, const char **errp)
183
{
184 12810
        s->sock = VTCP_listen_on(s->listen, "0", s->depth, errp);
185 12810
        if (*errp != NULL)
186 0
                return;
187 12810
        assert(s->sock > 0);
188 25620
        VTCP_myname(s->sock, s->aaddr, sizeof s->aaddr,
189 12810
            s->aport, sizeof s->aport);
190 12810
        macro_def(s->vl, s->name, "addr", "%s", s->aaddr);
191 12810
        macro_def(s->vl, s->name, "port", "%s", s->aport);
192 12810
        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 12810
        bprintf(s->listen, "%s %s", s->aaddr, s->aport);
195 12810
}
196
197
static void
198 13695
server_listen(struct server *s)
199
{
200
        const char *err;
201
202 13695
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
203
204 13695
        if (s->sock >= 0)
205 1080
                VTCP_close(&s->sock);
206 13695
        if (*s->listen != '/')
207 12810
                server_listen_tcp(s, &err);
208
        else
209 885
                server_listen_uds(s, &err);
210 13695
        if (err != NULL)
211 0
                vtc_fatal(s->vl,
212
                    "Server listen address (%s) cannot be resolved: %s",
213 0
                    s->listen, err);
214 13695
}
215
216
/**********************************************************************
217
 * Server thread
218
 */
219
220
static void *
221 13665
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 13665
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
233 13665
        assert(s->sock >= 0);
234
235 13665
        vl = vtc_logopen(s->name);
236 13665
        pthread_cleanup_push(vtc_logclose, vl);
237
238 27330
        vtc_log(vl, 2, "Started on %s (%u iterations%s)", s->listen,
239 13665
                s->repeat, s->keepalive ? " using keepalive" : "");
240 29999
        for (i = 0; i < s->repeat; i++) {
241 17834
                addr = (void*)&addr_s;
242 17834
                l = sizeof addr_s;
243 17834
                fd = accept(s->sock, addr, &l);
244 17834
                if (fd < 0)
245 0
                        vtc_fatal(vl, "Accept failed: %s", strerror(errno));
246 16648
                if (*s->listen != '/') {
247 15749
                        VTCP_hisname(fd, abuf, sizeof abuf, pbuf, sizeof pbuf);
248 15749
                        vtc_log(vl, 3, "accepted fd %d %s %s", fd, abuf, pbuf);
249 15749
                } else
250 900
                        vtc_log(vl, 3, "accepted fd %d 0.0.0.0 0", fd);
251 16649
                if (! s->keepalive)
252 33148
                        fd = http_process(vl, s->spec, fd, &s->sock, s->listen,
253 16574
                            s->rcvbuf);
254
                else
255 1575
                        while (fd >= 0 && i++ < s->repeat)
256 3000
                                fd = http_process(vl, s->spec, fd,
257 1500
                                    &s->sock, s->listen, s->rcvbuf);
258 16334
                vtc_log(vl, 3, "shutting fd %d", fd);
259 16334
                j = shutdown(fd, SHUT_WR);
260 16334
                if (!VTCP_Check(j))
261 0
                        vtc_fatal(vl, "Shutdown failed: %s", strerror(errno));
262 16334
                VTCP_close(&fd);
263 16334
        }
264 12165
        vtc_log(vl, 2, "Ending");
265 12165
        pthread_cleanup_pop(0);
266 12165
        vtc_logclose(vl);
267 12165
        return (NULL);
268
}
269
270
271
/**********************************************************************
272
 * Start the server thread
273
 */
274
275
static void
276 13665
server_start(struct server *s)
277
{
278 13665
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
279 13665
        vtc_log(s->vl, 2, "Starting server");
280 13665
        server_listen(s);
281 13665
        vtc_log(s->vl, 1, "Listen on %s", s->listen);
282 13665
        s->run = 1;
283 13665
        AZ(pthread_create(&s->tp, NULL, server_thread, s));
284 13665
}
285
286
/**********************************************************************
287
 */
288
289
static void *
290 185
server_dispatch_wrk(void *priv)
291
{
292
        struct server *s;
293
        struct vtclog *vl;
294
        int j, fd;
295
296 185
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
297 185
        assert(s->sock < 0);
298
299 185
        vl = vtc_logopen(s->name);
300 185
        pthread_cleanup_push(vtc_logclose, vl);
301
302 185
        fd = s->fd;
303
304 185
        vtc_log(vl, 3, "start with fd %d", fd);
305 185
        fd = http_process(vl, s->spec, fd, &s->sock, s->listen, s->rcvbuf);
306 185
        vtc_log(vl, 3, "shutting fd %d", fd);
307 185
        j = shutdown(fd, SHUT_WR);
308 185
        if (!VTCP_Check(j))
309 0
                vtc_fatal(vl, "Shutdown failed: %s", strerror(errno));
310 101
        VTCP_close(&s->fd);
311 101
        vtc_log(vl, 2, "Ending");
312 101
        pthread_cleanup_pop(0);
313 101
        vtc_logclose(vl);
314 101
        return (NULL);
315
}
316
317
static void *
318 30
server_dispatch_thread(void *priv)
319
{
320
        struct server *s, *s2;
321 30
        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 30
        CAST_OBJ_NOTNULL(s, priv, SERVER_MAGIC);
329 30
        assert(s->sock >= 0);
330
331 30
        vl = vtc_logopen(s->name);
332 30
        pthread_cleanup_push(vtc_logclose, vl);
333
334 30
        vtc_log(vl, 2, "Dispatch started on %s", s->listen);
335
336 215
        while (!vtc_stop) {
337 215
                addr = (void*)&addr_s;
338 215
                l = sizeof addr_s;
339 215
                fd = accept(s->sock, addr, &l);
340 215
                if (fd < 0)
341 0
                        vtc_fatal(vl, "Accepted failed: %s", strerror(errno));
342 185
                bprintf(snbuf, "s%d", sn++);
343 185
                vtc_log(vl, 3, "dispatch fd %d -> %s", fd, snbuf);
344 185
                s2 = server_new(snbuf, vl);
345 185
                s2->spec = s->spec;
346 185
                strcpy(s2->listen, s->listen);
347 185
                s2->fd = fd;
348 185
                s2->run = 1;
349 185
                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 30
server_dispatch(struct server *s)
358
{
359 30
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
360 30
        server_listen(s);
361 30
        vtc_log(s->vl, 2, "Starting dispatch server");
362 30
        s->run = 1;
363 30
        AZ(pthread_create(&s->tp, NULL, server_dispatch_thread, s));
364 30
}
365
366
/**********************************************************************
367
 * Force stop the server thread
368
 */
369
370
static void
371 30
server_break(struct server *s)
372
{
373
        void *res;
374
375 30
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
376 30
        vtc_log(s->vl, 2, "Breaking for server");
377 30
        (void)pthread_cancel(s->tp);
378 30
        AZ(pthread_join(s->tp, &res));
379 30
        VTCP_close(&s->sock);
380 30
        s->tp = 0;
381 30
        s->run = 0;
382 30
}
383
384
/**********************************************************************
385
 * Wait for server thread to stop
386
 */
387
388
static void
389 13850
server_wait(struct server *s)
390
{
391
        void *res;
392
393 13850
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
394 13850
        vtc_log(s->vl, 2, "Waiting for server (%d/%d)", s->sock, s->fd);
395 13850
        AZ(pthread_join(s->tp, &res));
396 13850
        if (res != NULL && !vtc_stop)
397 0
                vtc_fatal(s->vl, "Server returned \"%p\"",
398 0
                    (char *)res);
399 13850
        s->tp = 0;
400 13850
        s->run = 0;
401 13850
}
402
403
/**********************************************************************
404
 * Generate VCL backend decls for our servers
405
 */
406
407
void
408 10815
cmd_server_gen_vcl(struct vsb *vsb)
409
{
410
        struct server *s;
411
412 10815
        AZ(pthread_mutex_lock(&server_mtx));
413 22830
        VTAILQ_FOREACH(s, &servers, list) {
414 12015
                if (*s->listen != '/')
415 23490
                        VSB_printf(vsb,
416
                                   "backend %s { .host = \"%s\"; "
417
                                   ".port = \"%s\"; }\n",
418 11745
                                   s->name, s->aaddr, s->aport);
419
                else
420 540
                        VSB_printf(vsb,
421
                                   "backend %s { .path = \"%s\"; }\n",
422 270
                                   s->name, s->listen);
423 12015
        }
424 10815
        AZ(pthread_mutex_unlock(&server_mtx));
425 10815
}
426
427
428
/**********************************************************************
429
 * Generate VCL backend decls for our servers
430
 */
431
432
void
433 15
cmd_server_gen_haproxy_conf(struct vsb *vsb)
434
{
435
        struct server *s;
436
437 15
        AZ(pthread_mutex_lock(&server_mtx));
438 30
        VTAILQ_FOREACH(s, &servers, list) {
439 15
                if (*s->listen != '/')
440 30
                        VSB_printf(vsb,
441
                           "\n    backend be%s\n"
442
                           "\tserver srv%s %s:%s\n",
443 15
                           s->name + 1, s->name + 1, s->aaddr, s->aport);
444
                else
445 0
                        INCOMPL();
446 15
        }
447 30
        VTAILQ_FOREACH(s, &servers, list) {
448 15
                if (*s->listen != '/')
449 30
                        VSB_printf(vsb,
450
                           "\n    frontend http%s\n"
451
                           "\tuse_backend be%s\n"
452
                           "\tbind \"fd@${fe%s}\"\n",
453 15
                           s->name + 1, s->name + 1, s->name + 1);
454
                else
455 0
                        INCOMPL();
456 15
        }
457 15
        AZ(pthread_mutex_unlock(&server_mtx));
458 15
}
459
460
461
/**********************************************************************
462
 * Server command dispatch
463
 */
464
465
void
466 27300
cmd_server(CMD_ARGS)
467
{
468
        struct server *s;
469
470 27300
        (void)priv;
471 27300
        (void)cmd;
472
473 27300
        if (av == NULL) {
474
                /* Reset and free */
475 24755
                while (1) {
476 24755
                        AZ(pthread_mutex_lock(&server_mtx));
477 24755
                        s = VTAILQ_FIRST(&servers);
478 24755
                        CHECK_OBJ_ORNULL(s, SERVER_MAGIC);
479 24755
                        if (s != NULL)
480 12755
                                VTAILQ_REMOVE(&servers, s, list);
481 24755
                        AZ(pthread_mutex_unlock(&server_mtx));
482 24755
                        if (s == NULL)
483 12000
                                break;
484 12755
                        if (s->run) {
485 11795
                                (void)pthread_cancel(s->tp);
486 11795
                                server_wait(s);
487 11795
                        }
488 12755
                        if (s->sock >= 0)
489 12570
                                VTCP_close(&s->sock);
490 12755
                        server_delete(s);
491
                }
492 12000
                return;
493
        }
494
495 15300
        AZ(strcmp(av[0], "server"));
496 15300
        av++;
497
498 15300
        AZ(pthread_mutex_lock(&server_mtx));
499 19425
        VTAILQ_FOREACH(s, &servers, list)
500 6855
                if (!strcmp(s->name, av[0]))
501 2730
                        break;
502 15300
        AZ(pthread_mutex_unlock(&server_mtx));
503 15300
        if (s == NULL)
504 12570
                s = server_new(av[0], vl);
505 15300
        CHECK_OBJ_NOTNULL(s, SERVER_MAGIC);
506 15300
        av++;
507
508 45240
        for (; *av != NULL; av++) {
509 29940
                if (vtc_error)
510 0
                        break;
511 29940
                if (!strcmp(*av, "-wait")) {
512 1155
                        if (!s->run)
513 0
                                vtc_fatal(s->vl, "Server not -started");
514 1155
                        server_wait(s);
515 1155
                        continue;
516
                }
517
518 28785
                if (!strcmp(*av, "-break")) {
519 30
                        server_break(s);
520 30
                        continue;
521
                }
522
523
                /*
524
                 * We do an implict -wait if people muck about with a
525
                 * running server.
526
                 */
527 28755
                if (s->run)
528 900
                        server_wait(s);
529
530 28755
                AZ(s->run);
531 28755
                if (!strcmp(*av, "-repeat")) {
532 780
                        s->repeat = atoi(av[1]);
533 780
                        av++;
534 780
                        continue;
535
                }
536 27975
                if (!strcmp(*av, "-keepalive")) {
537 75
                        s->keepalive = 1;
538 75
                        continue;
539
                }
540 27900
                if (!strcmp(*av, "-listen")) {
541 795
                        if (s->sock >= 0)
542 15
                                VTCP_close(&s->sock);
543 795
                        bprintf(s->listen, "%s", av[1]);
544 795
                        av++;
545 795
                        continue;
546
                }
547 27105
                if (!strcmp(*av, "-rcvbuf")) {
548 0
                        s->rcvbuf = atoi(av[1]);
549 0
                        av++;
550 0
                        continue;
551
                }
552 27105
                if (!strcmp(*av, "-start")) {
553 13665
                        server_start(s);
554 13665
                        continue;
555
                }
556 13440
                if (!strcmp(*av, "-dispatch")) {
557 30
                        if (strcmp(s->name, "s0"))
558 0
                                vtc_fatal(s->vl,
559
                                    "server -dispatch only works on s0");
560 30
                        server_dispatch(s);
561 30
                        continue;
562
                }
563 13410
                if (**av == '-')
564 0
                        vtc_fatal(s->vl, "Unknown server argument: %s", *av);
565 13410
                s->spec = *av;
566 13410
        }
567 27300
}
568
569
void
570 12000
init_server(void)
571
{
572 12000
        AZ(pthread_mutex_init(&server_mtx, NULL));
573 12000
}