vinyl-cache/bin/vinyltest/vtest2/src/vtc_sess.c
0
/*-
1
 * Copyright (c) 2020 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
31
#include "config.h"
32
33
#include <stdlib.h>
34
#include <string.h>
35
36
#include "vtc.h"
37
#include "vtc_http.h"
38
39
struct thread_arg {
40
        unsigned                magic;
41
#define THREAD_ARG_MAGIC        0xd5dc5f1c
42
        void                    *priv;
43
        sess_conn_f             *conn_f;
44
        sess_disc_f             *disc_f;
45
        const char              *listen_addr;
46
        struct vtc_sess         *vsp;
47
        int                     *asocket;
48
        const char              *spec;
49
};
50
51
struct vtc_sess *
52 52719
Sess_New(struct vtclog *vl, const char *name)
53
{
54
        struct vtc_sess *vsp;
55
56 52719
        ALLOC_OBJ(vsp, VTC_SESS_MAGIC);
57 52719
        AN(vsp);
58 52719
        vsp->vl = vl;
59 52719
        REPLACE(vsp->name, name);
60 52719
        vsp->repeat = 1;
61 52719
        return (vsp);
62
}
63
64
void
65 52719
Sess_Destroy(struct vtc_sess **vspp)
66
{
67
        struct vtc_sess *vsp;
68
69 52719
        TAKE_OBJ_NOTNULL(vsp, vspp, VTC_SESS_MAGIC);
70 52719
        REPLACE(vsp->name, NULL);
71 52719
        FREE_OBJ(vsp);
72 52719
}
73
74
int
75 138684
Sess_GetOpt(struct vtc_sess *vsp, char * const **avp)
76
{
77
        char * const *av;
78 138684
        int rv = 0;
79
80 138684
        CHECK_OBJ_NOTNULL(vsp, VTC_SESS_MAGIC);
81 138684
        AN(avp);
82 138684
        av = *avp;
83 138684
        AN(*av);
84 138684
        if (!strcmp(*av, "-rcvbuf")) {
85 168
                AN(av[1]);
86 168
                vsp->rcvbuf = atoi(av[1]);
87 168
                av += 1;
88 168
                rv = 1;
89 138684
        } else if (!strcmp(*av, "-repeat")) {
90 2184
                AN(av[1]);
91 2184
                vsp->repeat = atoi(av[1]);
92 2184
                av += 1;
93 2184
                rv = 1;
94 138516
        } else if (!strcmp(*av, "-keepalive")) {
95 609
                vsp->keepalive = 1;
96 609
                rv = 1;
97 609
        }
98 138684
        *avp = av;
99 138684
        return (rv);
100
}
101
102
void
103 92344
sess_process(struct vtclog *vl, struct vtc_sess *vsp,
104
    const char *spec, int *sock, int *sfd, const char *addr)
105
{
106
107 92344
        CHECK_OBJ_NOTNULL(vsp, VTC_SESS_MAGIC);
108
109 92344
        http_process(vl, vsp, spec, sock, sfd, addr, vsp->rcvbuf);
110 92344
}
111
112
static void *
113 65340
sess_thread(void *priv)
114
{
115
        struct vtclog *vl;
116
        struct vtc_sess *vsp;
117
        struct thread_arg ta, *tap;
118 65340
        int i, fd = -1;
119
120 65340
        CAST_OBJ_NOTNULL(tap, priv, THREAD_ARG_MAGIC);
121 65340
        ta = *tap;
122 65340
        FREE_OBJ(tap);
123
124 65340
        vsp = ta.vsp;
125 65340
        CHECK_OBJ_NOTNULL(vsp, VTC_SESS_MAGIC);
126 65340
        vl = vtc_logopen("%s", vsp->name);
127 65340
        pthread_cleanup_push(vtc_logclose, vl);
128
129 65340
        assert(vsp->repeat > 0);
130 130680
        vtc_log(vl, 2, "Started on %s (%u iterations%s)", ta.listen_addr,
131 65340
                vsp->repeat, vsp->keepalive ? " using keepalive" : "");
132 154965
        for (i = 0; i < vsp->repeat; i++) {
133 89625
                if (fd < 0)
134 83056
                        fd = ta.conn_f(ta.priv, vl);
135 179250
                sess_process(vl, ta.vsp, ta.spec, &fd,
136 89625
                    ta.asocket, ta.listen_addr);
137 89625
                if (! vsp->keepalive)
138 79455
                        ta.disc_f(ta.priv, vl, &fd);
139 89625
        }
140 65340
        if (vsp->keepalive)
141 693
                ta.disc_f(ta.priv, vl, &fd);
142 65340
        vtc_log(vl, 2, "Ending");
143 65340
        pthread_cleanup_pop(0);
144 65340
        vtc_logclose(vl);
145 65340
        return (NULL);
146
}
147
148
pthread_t
149 65583
Sess_Start_Thread(
150
    void *priv,
151
    struct vtc_sess *vsp,
152
    sess_conn_f *conn,
153
    sess_disc_f *disc,
154
    const char *listen_addr,
155
    int *asocket,
156
    const char *spec
157
)
158
{
159
        struct thread_arg *ta;
160
        pthread_t pt;
161
162 65583
        AN(priv);
163 65583
        CHECK_OBJ_NOTNULL(vsp, VTC_SESS_MAGIC);
164 65583
        AN(conn);
165 65583
        AN(disc);
166 65583
        AN(listen_addr);
167 65583
        ALLOC_OBJ(ta, THREAD_ARG_MAGIC);
168 65583
        AN(ta);
169 65583
        ta->priv = priv;
170 65583
        ta->vsp = vsp;
171
172 65583
        ta->conn_f = conn;
173 65583
        ta->disc_f = disc;
174 65583
        ta->listen_addr = listen_addr;
175 65583
        ta->asocket = asocket;
176 65583
        ta->spec = spec;
177 65583
        PTOK(pthread_create(&pt, NULL, sess_thread, ta));
178 65583
        return (pt);
179
}