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