1 /*-
2  * Copyright (c) 2007-2015 Varnish Software AS
3  * All rights reserved.
4  *
5  * Author: Dag-Erling Smørgav <des@des.no>
6  *
7  * SPDX-License-Identifier: BSD-2-Clause
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * STEVEDORE: one who works at or is responsible for loading and
31  * unloading ships in port.  Example: "on the wharves, stevedores were
32  * unloading cargo from the far corners of the world." Origin: Spanish
33  * estibador, from estibar to pack.  First Known Use: 1788
34  */
35 
36 #include "config.h"
37 
38 #include "cache/cache_varnishd.h"
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 
43 #include "storage/storage.h"
44 #include "vrt_obj.h"
45 
46 static pthread_mutex_t stv_mtx;
47 
48 /*--------------------------------------------------------------------
49  * XXX: trust pointer writes to be atomic
50  */
51 
52 const struct stevedore *
STV_next()53 STV_next()
54 {
55 	static struct stevedore *stv;
56 	struct stevedore *r;
57 
58 	AZ(pthread_mutex_lock(&stv_mtx));
59 	if (!STV__iter(&stv))
60 		AN(STV__iter(&stv));
61 	if (stv == stv_transient) {
62 		stv = NULL;
63 		AN(STV__iter(&stv));
64 	}
65 	r = stv;
66 	AZ(pthread_mutex_unlock(&stv_mtx));
67 	AN(r);
68 	return (r);
69 }
70 
71 /*-------------------------------------------------------------------
72  * Allocate storage for an object, based on the header information.
73  * XXX: If we know (a hint of) the length, we could allocate space
74  * XXX: for the body in the same allocation while we are at it.
75  */
76 
77 int
STV_NewObject(struct worker * wrk,struct objcore * oc,const struct stevedore * stv,unsigned wsl)78 STV_NewObject(struct worker *wrk, struct objcore *oc,
79     const struct stevedore *stv, unsigned wsl)
80 {
81 	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
82 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
83 	CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);
84 	assert(wsl > 0);
85 
86 	wrk->strangelove = cache_param->nuke_limit;
87 	AN(stv->allocobj);
88 	if (stv->allocobj(wrk, stv, oc, wsl) == 0)
89 		return (0);
90 	oc->oa_present = 0;
91 	wrk->stats->n_object++;
92 	VSLb(wrk->vsl, SLT_Storage, "%s %s",
93 	    oc->stobj->stevedore->name, oc->stobj->stevedore->ident);
94 	return (1);
95 }
96 
97 /*-------------------------------------------------------------------*/
98 
99 void
STV_open(void)100 STV_open(void)
101 {
102 	struct stevedore *stv;
103 	char buf[1024];
104 
105 	ASSERT_CLI();
106 	AZ(pthread_mutex_init(&stv_mtx, NULL));
107 	STV_Foreach(stv) {
108 		bprintf(buf, "storage.%s", stv->ident);
109 		stv->vclname = strdup(buf);
110 		AN(stv->vclname);
111 		if (stv->open != NULL)
112 			stv->open(stv);
113 	}
114 }
115 
116 void
STV_close(void)117 STV_close(void)
118 {
119 	struct stevedore *stv;
120 	int i;
121 
122 	ASSERT_CLI();
123 	for (i = 1; i >= 0; i--) {
124 		/* First send close warning */
125 		STV_Foreach(stv)
126 			if (stv->close != NULL)
127 				stv->close(stv, i);
128 	}
129 }
130 
131 /*-------------------------------------------------------------------
132  * Notify the stevedores of BAN related events. A non-zero return
133  * value indicates that the stevedore is unable to persist the
134  * event.
135  */
136 
137 int
STV_BanInfoDrop(const uint8_t * ban,unsigned len)138 STV_BanInfoDrop(const uint8_t *ban, unsigned len)
139 {
140 	struct stevedore *stv;
141 	int r = 0;
142 
143 	STV_Foreach(stv)
144 		if (stv->baninfo != NULL)
145 			r |= stv->baninfo(stv, BI_DROP, ban, len);
146 
147 	return (r);
148 }
149 
150 int
STV_BanInfoNew(const uint8_t * ban,unsigned len)151 STV_BanInfoNew(const uint8_t *ban, unsigned len)
152 {
153 	struct stevedore *stv;
154 	int r = 0;
155 
156 	STV_Foreach(stv)
157 		if (stv->baninfo != NULL)
158 			r |= stv->baninfo(stv, BI_NEW, ban, len);
159 
160 	return (r);
161 }
162 
163 /*-------------------------------------------------------------------
164  * Export a complete ban list to the stevedores for persistence.
165  * The stevedores should clear any previous ban lists and replace
166  * them with this list.
167  */
168 
169 void
STV_BanExport(const uint8_t * bans,unsigned len)170 STV_BanExport(const uint8_t *bans, unsigned len)
171 {
172 	struct stevedore *stv;
173 
174 	STV_Foreach(stv)
175 		if (stv->banexport != NULL)
176 			stv->banexport(stv, bans, len);
177 }
178 
179 /*--------------------------------------------------------------------
180  * VRT functions for stevedores
181  */
182 
183 static const struct stevedore *
stv_find(const char * nm)184 stv_find(const char *nm)
185 {
186 	struct stevedore *stv;
187 
188 	STV_Foreach(stv)
189 		if (!strcmp(stv->ident, nm))
190 			return (stv);
191 	return (NULL);
192 }
193 
194 int
VRT_Stv(const char * nm)195 VRT_Stv(const char *nm)
196 {
197 
198 	if (stv_find(nm) != NULL)
199 		return (1);
200 	return (0);
201 }
202 
v_matchproto_()203 const char * v_matchproto_()
204 VRT_STEVEDORE_string(VCL_STEVEDORE s)
205 {
206 	if (s == NULL)
207 		return (NULL);
208 	CHECK_OBJ_NOTNULL(s, STEVEDORE_MAGIC);
209 	return (s->vclname);
210 }
211 
212 VCL_STEVEDORE
VRT_stevedore(const char * nm)213 VRT_stevedore(const char *nm)
214 {
215 	return (stv_find(nm));
216 }
217 
218 #define VRTSTVVAR(nm, vtype, ctype, dval)		\
219 ctype							\
220 VRT_stevedore_##nm(VCL_STEVEDORE stv)			\
221 {							\
222 	if (stv == NULL)				\
223 		return (0);				\
224 	CHECK_OBJ_NOTNULL(stv, STEVEDORE_MAGIC);	\
225 	return (stv->var_##nm(stv));			\
226 }
227 #include "tbl/vrt_stv_var.h"
228