1 /*
2  * Sample management functions.
3  *
4  * Copyright 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5  * Copyright (C) 2012 Willy Tarreau <w@1wt.eu>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version
10  * 2 of the License, or (at your option) any later version.
11  *
12  */
13 
14 #include <ctype.h>
15 #include <string.h>
16 #include <arpa/inet.h>
17 #include <stdio.h>
18 
19 #include <types/global.h>
20 
21 #include <common/chunk.h>
22 #include <common/hash.h>
23 #include <common/http.h>
24 #include <common/initcall.h>
25 #include <common/standard.h>
26 #include <common/uri_auth.h>
27 #include <common/base64.h>
28 
29 #include <proto/arg.h>
30 #include <proto/auth.h>
31 #include <proto/log.h>
32 #include <proto/proxy.h>
33 #include <proto/protocol_buffers.h>
34 #include <proto/sample.h>
35 #include <proto/sink.h>
36 #include <proto/stick_table.h>
37 #include <proto/vars.h>
38 
39 #include <import/sha1.h>
40 #include <import/xxhash.h>
41 
42 /* sample type names */
43 const char *smp_to_type[SMP_TYPES] = {
44 	[SMP_T_ANY]  = "any",
45 	[SMP_T_BOOL] = "bool",
46 	[SMP_T_SINT] = "sint",
47 	[SMP_T_ADDR] = "addr",
48 	[SMP_T_IPV4] = "ipv4",
49 	[SMP_T_IPV6] = "ipv6",
50 	[SMP_T_STR]  = "str",
51 	[SMP_T_BIN]  = "bin",
52 	[SMP_T_METH] = "meth",
53 };
54 
55 /* static sample used in sample_process() when <p> is NULL */
56 static THREAD_LOCAL struct sample temp_smp;
57 
58 /* list head of all known sample fetch keywords */
59 static struct sample_fetch_kw_list sample_fetches = {
60 	.list = LIST_HEAD_INIT(sample_fetches.list)
61 };
62 
63 /* list head of all known sample format conversion keywords */
64 static struct sample_conv_kw_list sample_convs = {
65 	.list = LIST_HEAD_INIT(sample_convs.list)
66 };
67 
68 const unsigned int fetch_cap[SMP_SRC_ENTRIES] = {
69 	[SMP_SRC_INTRN] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
70 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
71 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
72 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
73 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
74 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
75 	                   SMP_VAL_FE_LOG_END),
76 
77 	[SMP_SRC_LISTN] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
78 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
79 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
80 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
81 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
82 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
83 	                   SMP_VAL_FE_LOG_END),
84 
85 	[SMP_SRC_FTEND] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
86 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
87 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
88 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
89 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
90 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
91 	                   SMP_VAL_FE_LOG_END),
92 
93 	[SMP_SRC_L4CLI] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
94 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
95 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
96 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
97 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
98 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
99 	                   SMP_VAL_FE_LOG_END),
100 
101 	[SMP_SRC_L5CLI] = (SMP_VAL___________ | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
102 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
103 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
104 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
105 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
106 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
107 	                   SMP_VAL_FE_LOG_END),
108 
109 	[SMP_SRC_TRACK] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
110 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
111 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
112 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
113 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
114 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
115 	                   SMP_VAL_FE_LOG_END),
116 
117 	[SMP_SRC_L6REQ] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_FE_REQ_CNT |
118 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
119 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
120 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL___________ |
121 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
122 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
123 	                   SMP_VAL___________),
124 
125 	[SMP_SRC_HRQHV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_FE_REQ_CNT |
126 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
127 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
128 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL___________ |
129 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
130 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
131 	                   SMP_VAL___________),
132 
133 	[SMP_SRC_HRQHP] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_FE_REQ_CNT |
134 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
135 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
136 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
137 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
138 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
139 	                   SMP_VAL_FE_LOG_END),
140 
141 	[SMP_SRC_HRQBO] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
142 	                   SMP_VAL___________ | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
143 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
144 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL___________ |
145 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
146 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
147 	                   SMP_VAL___________),
148 
149 	[SMP_SRC_BKEND] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
150 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
151 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
152 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
153 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
154 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
155 	                   SMP_VAL_FE_LOG_END),
156 
157 	[SMP_SRC_SERVR] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
158 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
159 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
160 	                   SMP_VAL___________ | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
161 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
162 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
163 	                   SMP_VAL_FE_LOG_END),
164 
165 	[SMP_SRC_L4SRV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
166 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
167 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
168 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
169 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
170 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
171 	                   SMP_VAL_FE_LOG_END),
172 
173 	[SMP_SRC_L5SRV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
174 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
175 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
176 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
177 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
178 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
179 	                   SMP_VAL_FE_LOG_END),
180 
181 	[SMP_SRC_L6RES] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
182 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
183 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
184 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
185 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
186 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
187 	                   SMP_VAL___________),
188 
189 	[SMP_SRC_HRSHV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
190 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
191 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
192 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
193 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
194 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
195 	                   SMP_VAL___________),
196 
197 	[SMP_SRC_HRSHP] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
198 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
199 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
200 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
201 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
202 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
203 	                   SMP_VAL_FE_LOG_END),
204 
205 	[SMP_SRC_HRSBO] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
206 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
207 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
208 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
209 	                   SMP_VAL___________ | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
210 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
211 	                   SMP_VAL___________),
212 
213 	[SMP_SRC_RQFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
214 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
215 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
216 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
217 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
218 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
219 	                   SMP_VAL_FE_LOG_END),
220 
221 	[SMP_SRC_RSFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
222 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
223 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
224 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
225 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
226 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
227 	                   SMP_VAL_FE_LOG_END),
228 
229 	[SMP_SRC_TXFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
230 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
231 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
232 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
233 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
234 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
235 	                   SMP_VAL_FE_LOG_END),
236 
237 	[SMP_SRC_SSFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
238 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
239 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
240 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
241 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
242 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
243 	                   SMP_VAL_FE_LOG_END),
244 };
245 
246 static const char *fetch_src_names[SMP_SRC_ENTRIES] = {
247 	[SMP_SRC_INTRN] = "internal state",
248 	[SMP_SRC_LISTN] = "listener",
249 	[SMP_SRC_FTEND] = "frontend",
250 	[SMP_SRC_L4CLI] = "client address",
251 	[SMP_SRC_L5CLI] = "client-side connection",
252 	[SMP_SRC_TRACK] = "track counters",
253 	[SMP_SRC_L6REQ] = "request buffer",
254 	[SMP_SRC_HRQHV] = "HTTP request headers",
255 	[SMP_SRC_HRQHP] = "HTTP request",
256 	[SMP_SRC_HRQBO] = "HTTP request body",
257 	[SMP_SRC_BKEND] = "backend",
258 	[SMP_SRC_SERVR] = "server",
259 	[SMP_SRC_L4SRV] = "server address",
260 	[SMP_SRC_L5SRV] = "server-side connection",
261 	[SMP_SRC_L6RES] = "response buffer",
262 	[SMP_SRC_HRSHV] = "HTTP response headers",
263 	[SMP_SRC_HRSHP] = "HTTP response",
264 	[SMP_SRC_HRSBO] = "HTTP response body",
265 	[SMP_SRC_RQFIN] = "request buffer statistics",
266 	[SMP_SRC_RSFIN] = "response buffer statistics",
267 	[SMP_SRC_TXFIN] = "transaction statistics",
268 	[SMP_SRC_SSFIN] = "session statistics",
269 };
270 
271 static const char *fetch_ckp_names[SMP_CKP_ENTRIES] = {
272 	[SMP_CKP_FE_CON_ACC] = "frontend tcp-request connection rule",
273 	[SMP_CKP_FE_SES_ACC] = "frontend tcp-request session rule",
274 	[SMP_CKP_FE_REQ_CNT] = "frontend tcp-request content rule",
275 	[SMP_CKP_FE_HRQ_HDR] = "frontend http-request header rule",
276 	[SMP_CKP_FE_HRQ_BDY] = "frontend http-request body rule",
277 	[SMP_CKP_FE_SET_BCK] = "frontend use-backend rule",
278 	[SMP_CKP_BE_REQ_CNT] = "backend tcp-request content rule",
279 	[SMP_CKP_BE_HRQ_HDR] = "backend http-request header rule",
280 	[SMP_CKP_BE_HRQ_BDY] = "backend http-request body rule",
281 	[SMP_CKP_BE_SET_SRV] = "backend use-server, balance or stick-match rule",
282 	[SMP_CKP_BE_SRV_CON] = "server source selection",
283 	[SMP_CKP_BE_RES_CNT] = "backend tcp-response content rule",
284 	[SMP_CKP_BE_HRS_HDR] = "backend http-response header rule",
285 	[SMP_CKP_BE_HRS_BDY] = "backend http-response body rule",
286 	[SMP_CKP_BE_STO_RUL] = "backend stick-store rule",
287 	[SMP_CKP_FE_RES_CNT] = "frontend tcp-response content rule",
288 	[SMP_CKP_FE_HRS_HDR] = "frontend http-response header rule",
289 	[SMP_CKP_FE_HRS_BDY] = "frontend http-response body rule",
290 	[SMP_CKP_FE_LOG_END] = "logs",
291 };
292 
293 /* This function returns the type of the data returned by the sample_expr.
294  * It assumes that the <expr> and all of its converters are properly
295  * initialized.
296  */
297 inline
smp_expr_output_type(struct sample_expr * expr)298 int smp_expr_output_type(struct sample_expr *expr)
299 {
300 	struct sample_conv_expr *smp_expr;
301 
302 	if (!LIST_ISEMPTY(&expr->conv_exprs)) {
303 		smp_expr = LIST_PREV(&expr->conv_exprs, struct sample_conv_expr *, list);
304 		return smp_expr->conv->out_type;
305 	}
306 	return expr->fetch->out_type;
307 }
308 
309 
310 /* fill the trash with a comma-delimited list of source names for the <use> bit
311  * field which must be composed of a non-null set of SMP_USE_* flags. The return
312  * value is the pointer to the string in the trash buffer.
313  */
sample_src_names(unsigned int use)314 const char *sample_src_names(unsigned int use)
315 {
316 	int bit;
317 
318 	trash.data = 0;
319 	trash.area[0] = '\0';
320 	for (bit = 0; bit < SMP_SRC_ENTRIES; bit++) {
321 		if (!(use & ~((1 << bit) - 1)))
322 			break; /* no more bits */
323 
324 		if (!(use & (1 << bit)))
325 			continue; /* bit not set */
326 
327 		trash.data += snprintf(trash.area + trash.data,
328 				       trash.size - trash.data, "%s%s",
329 				       (use & ((1 << bit) - 1)) ? "," : "",
330 				       fetch_src_names[bit]);
331 	}
332 	return trash.area;
333 }
334 
335 /* return a pointer to the correct sample checkpoint name, or "unknown" when
336  * the flags are invalid. Only the lowest bit is used, higher bits are ignored
337  * if set.
338  */
sample_ckp_names(unsigned int use)339 const char *sample_ckp_names(unsigned int use)
340 {
341 	int bit;
342 
343 	for (bit = 0; bit < SMP_CKP_ENTRIES; bit++)
344 		if (use & (1 << bit))
345 			return fetch_ckp_names[bit];
346 	return "unknown sample check place, please report this bug";
347 }
348 
349 /*
350  * Registers the sample fetch keyword list <kwl> as a list of valid keywords
351  * for next parsing sessions. The fetch keywords capabilities are also computed
352  * from their ->use field.
353  */
sample_register_fetches(struct sample_fetch_kw_list * kwl)354 void sample_register_fetches(struct sample_fetch_kw_list *kwl)
355 {
356 	struct sample_fetch *sf;
357 	int bit;
358 
359 	for (sf = kwl->kw; sf->kw != NULL; sf++) {
360 		for (bit = 0; bit < SMP_SRC_ENTRIES; bit++)
361 			if (sf->use & (1 << bit))
362 				sf->val |= fetch_cap[bit];
363 	}
364 	LIST_ADDQ(&sample_fetches.list, &kwl->list);
365 }
366 
367 /*
368  * Registers the sample format coverstion keyword list <pckl> as a list of valid keywords for next
369  * parsing sessions.
370  */
sample_register_convs(struct sample_conv_kw_list * pckl)371 void sample_register_convs(struct sample_conv_kw_list *pckl)
372 {
373 	LIST_ADDQ(&sample_convs.list, &pckl->list);
374 }
375 
376 /*
377  * Returns the pointer on sample fetch keyword structure identified by
378  * string of <len> in buffer <kw>.
379  *
380  */
find_sample_fetch(const char * kw,int len)381 struct sample_fetch *find_sample_fetch(const char *kw, int len)
382 {
383 	int index;
384 	struct sample_fetch_kw_list *kwl;
385 
386 	list_for_each_entry(kwl, &sample_fetches.list, list) {
387 		for (index = 0; kwl->kw[index].kw != NULL; index++) {
388 			if (strncmp(kwl->kw[index].kw, kw, len) == 0 &&
389 			    kwl->kw[index].kw[len] == '\0')
390 				return &kwl->kw[index];
391 		}
392 	}
393 	return NULL;
394 }
395 
396 /* This function browses the list of available sample fetches. <current> is
397  * the last used sample fetch. If it is the first call, it must set to NULL.
398  * <idx> is the index of the next sample fetch entry. It is used as private
399  * value. It is useless to initiate it.
400  *
401  * It returns always the new fetch_sample entry, and NULL when the end of
402  * the list is reached.
403  */
sample_fetch_getnext(struct sample_fetch * current,int * idx)404 struct sample_fetch *sample_fetch_getnext(struct sample_fetch *current, int *idx)
405 {
406 	struct sample_fetch_kw_list *kwl;
407 	struct sample_fetch *base;
408 
409 	if (!current) {
410 		/* Get first kwl entry. */
411 		kwl = LIST_NEXT(&sample_fetches.list, struct sample_fetch_kw_list *, list);
412 		(*idx) = 0;
413 	} else {
414 		/* Get kwl corresponding to the curret entry. */
415 		base = current + 1 - (*idx);
416 		kwl = container_of(base, struct sample_fetch_kw_list, kw);
417 	}
418 
419 	while (1) {
420 
421 		/* Check if kwl is the last entry. */
422 		if (&kwl->list == &sample_fetches.list)
423 			return NULL;
424 
425 		/* idx contain the next keyword. If it is available, return it. */
426 		if (kwl->kw[*idx].kw) {
427 			(*idx)++;
428 			return &kwl->kw[(*idx)-1];
429 		}
430 
431 		/* get next entry in the main list, and return NULL if the end is reached. */
432 		kwl = LIST_NEXT(&kwl->list, struct sample_fetch_kw_list *, list);
433 
434 		/* Set index to 0, ans do one other loop. */
435 		(*idx) = 0;
436 	}
437 }
438 
439 /* This function browses the list of available converters. <current> is
440  * the last used converter. If it is the first call, it must set to NULL.
441  * <idx> is the index of the next converter entry. It is used as private
442  * value. It is useless to initiate it.
443  *
444  * It returns always the next sample_conv entry, and NULL when the end of
445  * the list is reached.
446  */
sample_conv_getnext(struct sample_conv * current,int * idx)447 struct sample_conv *sample_conv_getnext(struct sample_conv *current, int *idx)
448 {
449 	struct sample_conv_kw_list *kwl;
450 	struct sample_conv *base;
451 
452 	if (!current) {
453 		/* Get first kwl entry. */
454 		kwl = LIST_NEXT(&sample_convs.list, struct sample_conv_kw_list *, list);
455 		(*idx) = 0;
456 	} else {
457 		/* Get kwl corresponding to the curret entry. */
458 		base = current + 1 - (*idx);
459 		kwl = container_of(base, struct sample_conv_kw_list, kw);
460 	}
461 
462 	while (1) {
463 		/* Check if kwl is the last entry. */
464 		if (&kwl->list == &sample_convs.list)
465 			return NULL;
466 
467 		/* idx contain the next keyword. If it is available, return it. */
468 		if (kwl->kw[*idx].kw) {
469 			(*idx)++;
470 			return &kwl->kw[(*idx)-1];
471 		}
472 
473 		/* get next entry in the main list, and return NULL if the end is reached. */
474 		kwl = LIST_NEXT(&kwl->list, struct sample_conv_kw_list *, list);
475 
476 		/* Set index to 0, ans do one other loop. */
477 		(*idx) = 0;
478 	}
479 }
480 
481 /*
482  * Returns the pointer on sample format conversion keyword structure identified by
483  * string of <len> in buffer <kw>.
484  *
485  */
find_sample_conv(const char * kw,int len)486 struct sample_conv *find_sample_conv(const char *kw, int len)
487 {
488 	int index;
489 	struct sample_conv_kw_list *kwl;
490 
491 	list_for_each_entry(kwl, &sample_convs.list, list) {
492 		for (index = 0; kwl->kw[index].kw != NULL; index++) {
493 			if (strncmp(kwl->kw[index].kw, kw, len) == 0 &&
494 			    kwl->kw[index].kw[len] == '\0')
495 				return &kwl->kw[index];
496 		}
497 	}
498 	return NULL;
499 }
500 
501 /******************************************************************/
502 /*          Sample casts functions                                */
503 /******************************************************************/
504 
c_ip2int(struct sample * smp)505 static int c_ip2int(struct sample *smp)
506 {
507 	smp->data.u.sint = ntohl(smp->data.u.ipv4.s_addr);
508 	smp->data.type = SMP_T_SINT;
509 	return 1;
510 }
511 
c_ip2str(struct sample * smp)512 static int c_ip2str(struct sample *smp)
513 {
514 	struct buffer *trash = get_trash_chunk();
515 
516 	if (!inet_ntop(AF_INET, (void *)&smp->data.u.ipv4, trash->area, trash->size))
517 		return 0;
518 
519 	trash->data = strlen(trash->area);
520 	smp->data.u.str = *trash;
521 	smp->data.type = SMP_T_STR;
522 	smp->flags &= ~SMP_F_CONST;
523 
524 	return 1;
525 }
526 
c_ip2ipv6(struct sample * smp)527 static int c_ip2ipv6(struct sample *smp)
528 {
529 	v4tov6(&smp->data.u.ipv6, &smp->data.u.ipv4);
530 	smp->data.type = SMP_T_IPV6;
531 	return 1;
532 }
533 
c_ipv62ip(struct sample * smp)534 static int c_ipv62ip(struct sample *smp)
535 {
536 	if (!v6tov4(&smp->data.u.ipv4, &smp->data.u.ipv6))
537 		return 0;
538 	smp->data.type = SMP_T_IPV4;
539 	return 1;
540 }
541 
c_ipv62str(struct sample * smp)542 static int c_ipv62str(struct sample *smp)
543 {
544 	struct buffer *trash = get_trash_chunk();
545 
546 	if (!inet_ntop(AF_INET6, (void *)&smp->data.u.ipv6, trash->area, trash->size))
547 		return 0;
548 
549 	trash->data = strlen(trash->area);
550 	smp->data.u.str = *trash;
551 	smp->data.type = SMP_T_STR;
552 	smp->flags &= ~SMP_F_CONST;
553 	return 1;
554 }
555 
556 /*
557 static int c_ipv62ip(struct sample *smp)
558 {
559 	return v6tov4(&smp->data.u.ipv4, &smp->data.u.ipv6);
560 }
561 */
562 
c_int2ip(struct sample * smp)563 static int c_int2ip(struct sample *smp)
564 {
565 	smp->data.u.ipv4.s_addr = htonl((unsigned int)smp->data.u.sint);
566 	smp->data.type = SMP_T_IPV4;
567 	return 1;
568 }
569 
c_int2ipv6(struct sample * smp)570 static int c_int2ipv6(struct sample *smp)
571 {
572 	smp->data.u.ipv4.s_addr = htonl((unsigned int)smp->data.u.sint);
573 	v4tov6(&smp->data.u.ipv6, &smp->data.u.ipv4);
574 	smp->data.type = SMP_T_IPV6;
575 	return 1;
576 }
577 
c_str2addr(struct sample * smp)578 static int c_str2addr(struct sample *smp)
579 {
580 	if (!buf2ip(smp->data.u.str.area, smp->data.u.str.data, &smp->data.u.ipv4)) {
581 		if (!buf2ip6(smp->data.u.str.area, smp->data.u.str.data, &smp->data.u.ipv6))
582 			return 0;
583 		smp->data.type = SMP_T_IPV6;
584 		smp->flags &= ~SMP_F_CONST;
585 		return 1;
586 	}
587 	smp->data.type = SMP_T_IPV4;
588 	smp->flags &= ~SMP_F_CONST;
589 	return 1;
590 }
591 
c_str2ip(struct sample * smp)592 static int c_str2ip(struct sample *smp)
593 {
594 	if (!buf2ip(smp->data.u.str.area, smp->data.u.str.data, &smp->data.u.ipv4))
595 		return 0;
596 	smp->data.type = SMP_T_IPV4;
597 	smp->flags &= ~SMP_F_CONST;
598 	return 1;
599 }
600 
c_str2ipv6(struct sample * smp)601 static int c_str2ipv6(struct sample *smp)
602 {
603 	if (!buf2ip6(smp->data.u.str.area, smp->data.u.str.data, &smp->data.u.ipv6))
604 		return 0;
605 	smp->data.type = SMP_T_IPV6;
606 	smp->flags &= ~SMP_F_CONST;
607 	return 1;
608 }
609 
610 /*
611  * The NULL char always enforces the end of string if it is met.
612  * Data is never changed, so we can ignore the CONST case
613  */
c_bin2str(struct sample * smp)614 static int c_bin2str(struct sample *smp)
615 {
616 	int i;
617 
618 	for (i = 0; i < smp->data.u.str.data; i++) {
619 		if (!smp->data.u.str.area[i]) {
620 			smp->data.u.str.data = i;
621 			break;
622 		}
623 	}
624 	return 1;
625 }
626 
c_int2str(struct sample * smp)627 static int c_int2str(struct sample *smp)
628 {
629 	struct buffer *trash = get_trash_chunk();
630 	char *pos;
631 
632 	pos = lltoa_r(smp->data.u.sint, trash->area, trash->size);
633 	if (!pos)
634 		return 0;
635 
636 	trash->size = trash->size - (pos - trash->area);
637 	trash->area = pos;
638 	trash->data = strlen(pos);
639 	smp->data.u.str = *trash;
640 	smp->data.type = SMP_T_STR;
641 	smp->flags &= ~SMP_F_CONST;
642 	return 1;
643 }
644 
645 /* This function unconditionally duplicates data and removes the "const" flag.
646  * For strings and binary blocks, it also provides a known allocated size with
647  * a length that is capped to the size, and ensures a trailing zero is always
648  * appended for strings. This is necessary for some operations which may
649  * require to extend the length. It returns 0 if it fails, 1 on success.
650  */
smp_dup(struct sample * smp)651 int smp_dup(struct sample *smp)
652 {
653 	struct buffer *trash;
654 
655 	switch (smp->data.type) {
656 	case SMP_T_BOOL:
657 	case SMP_T_SINT:
658 	case SMP_T_ADDR:
659 	case SMP_T_IPV4:
660 	case SMP_T_IPV6:
661 		/* These type are not const. */
662 		break;
663 
664 	case SMP_T_METH:
665 		if (smp->data.u.meth.meth != HTTP_METH_OTHER)
666 			break;
667 		/* Fall through */
668 
669 	case SMP_T_STR:
670 		trash = get_trash_chunk();
671 		trash->data = smp->data.type == SMP_T_STR ?
672 		    smp->data.u.str.data : smp->data.u.meth.str.data;
673 		if (trash->data > trash->size - 1)
674 			trash->data = trash->size - 1;
675 
676 		memcpy(trash->area, smp->data.type == SMP_T_STR ?
677 		    smp->data.u.str.area : smp->data.u.meth.str.area,
678 		    trash->data);
679 		trash->area[trash->data] = 0;
680 		smp->data.u.str = *trash;
681 		break;
682 
683 	case SMP_T_BIN:
684 		trash = get_trash_chunk();
685 		trash->data = smp->data.u.str.data;
686 		if (trash->data > trash->size)
687 			trash->data = trash->size;
688 
689 		memcpy(trash->area, smp->data.u.str.area, trash->data);
690 		smp->data.u.str = *trash;
691 		break;
692 
693 	default:
694 		/* Other cases are unexpected. */
695 		return 0;
696 	}
697 
698 	/* remove const flag */
699 	smp->flags &= ~SMP_F_CONST;
700 	return 1;
701 }
702 
c_none(struct sample * smp)703 int c_none(struct sample *smp)
704 {
705 	return 1;
706 }
707 
c_str2int(struct sample * smp)708 static int c_str2int(struct sample *smp)
709 {
710 	const char *str;
711 	const char *end;
712 
713 	if (smp->data.u.str.data == 0)
714 		return 0;
715 
716 	str = smp->data.u.str.area;
717 	end = smp->data.u.str.area + smp->data.u.str.data;
718 
719 	smp->data.u.sint = read_int64(&str, end);
720 	smp->data.type = SMP_T_SINT;
721 	smp->flags &= ~SMP_F_CONST;
722 	return 1;
723 }
724 
c_str2meth(struct sample * smp)725 static int c_str2meth(struct sample *smp)
726 {
727 	enum http_meth_t meth;
728 	int len;
729 
730 	meth = find_http_meth(smp->data.u.str.area, smp->data.u.str.data);
731 	if (meth == HTTP_METH_OTHER) {
732 		len = smp->data.u.str.data;
733 		smp->data.u.meth.str.area = smp->data.u.str.area;
734 		smp->data.u.meth.str.data = len;
735 	}
736 	else
737 		smp->flags &= ~SMP_F_CONST;
738 	smp->data.u.meth.meth = meth;
739 	smp->data.type = SMP_T_METH;
740 	return 1;
741 }
742 
c_meth2str(struct sample * smp)743 static int c_meth2str(struct sample *smp)
744 {
745 	int len;
746 	enum http_meth_t meth;
747 
748 	if (smp->data.u.meth.meth == HTTP_METH_OTHER) {
749 		/* The method is unknown. Copy the original pointer. */
750 		len = smp->data.u.meth.str.data;
751 		smp->data.u.str.area = smp->data.u.meth.str.area;
752 		smp->data.u.str.data = len;
753 		smp->data.type = SMP_T_STR;
754 	}
755 	else if (smp->data.u.meth.meth < HTTP_METH_OTHER) {
756 		/* The method is known, copy the pointer containing the string. */
757 		meth = smp->data.u.meth.meth;
758 		smp->data.u.str.area = http_known_methods[meth].ptr;
759 		smp->data.u.str.data = http_known_methods[meth].len;
760 		smp->flags |= SMP_F_CONST;
761 		smp->data.type = SMP_T_STR;
762 	}
763 	else {
764 		/* Unknown method */
765 		return 0;
766 	}
767 	return 1;
768 }
769 
c_addr2bin(struct sample * smp)770 static int c_addr2bin(struct sample *smp)
771 {
772 	struct buffer *chk = get_trash_chunk();
773 
774 	if (smp->data.type == SMP_T_IPV4) {
775 		chk->data = 4;
776 		memcpy(chk->area, &smp->data.u.ipv4, chk->data);
777 	}
778 	else if (smp->data.type == SMP_T_IPV6) {
779 		chk->data = 16;
780 		memcpy(chk->area, &smp->data.u.ipv6, chk->data);
781 	}
782 	else
783 		return 0;
784 
785 	smp->data.u.str = *chk;
786 	smp->data.type = SMP_T_BIN;
787 	return 1;
788 }
789 
c_int2bin(struct sample * smp)790 static int c_int2bin(struct sample *smp)
791 {
792 	struct buffer *chk = get_trash_chunk();
793 
794 	*(unsigned long long int *) chk->area = my_htonll(smp->data.u.sint);
795 	chk->data = 8;
796 
797 	smp->data.u.str = *chk;
798 	smp->data.type = SMP_T_BIN;
799 	return 1;
800 }
801 
802 
803 /*****************************************************************/
804 /*      Sample casts matrix:                                     */
805 /*           sample_casts[from type][to type]                    */
806 /*           NULL pointer used for impossible sample casts       */
807 /*****************************************************************/
808 
809 sample_cast_fct sample_casts[SMP_TYPES][SMP_TYPES] = {
810 /*            to:  ANY     BOOL       SINT       ADDR        IPV4      IPV6        STR         BIN         METH */
811 /* from:  ANY */ { c_none, c_none,    c_none,    c_none,     c_none,   c_none,     c_none,     c_none,     c_none,     },
812 /*       BOOL */ { c_none, c_none,    c_none,    NULL,       NULL,     NULL,       c_int2str,  NULL,       NULL,       },
813 /*       SINT */ { c_none, c_none,    c_none,    c_int2ip,   c_int2ip, c_int2ipv6, c_int2str,  c_int2bin,  NULL,       },
814 /*       ADDR */ { c_none, NULL,      NULL,      NULL,       NULL,     NULL,       NULL,       NULL,       NULL,       },
815 /*       IPV4 */ { c_none, NULL,      c_ip2int,  c_none,     c_none,   c_ip2ipv6,  c_ip2str,   c_addr2bin, NULL,       },
816 /*       IPV6 */ { c_none, NULL,      NULL,      c_none,     c_ipv62ip,c_none,     c_ipv62str, c_addr2bin, NULL,       },
817 /*        STR */ { c_none, c_str2int, c_str2int, c_str2addr, c_str2ip, c_str2ipv6, c_none,     c_none,     c_str2meth, },
818 /*        BIN */ { c_none, NULL,      NULL,      NULL,       NULL,     NULL,       c_bin2str,  c_none,     c_str2meth, },
819 /*       METH */ { c_none, NULL,      NULL,      NULL,       NULL,     NULL,       c_meth2str, c_meth2str, c_none,     }
820 };
821 
822 /*
823  * Parse a sample expression configuration:
824  *        fetch keyword followed by format conversion keywords.
825  * Returns a pointer on allocated sample expression structure.
826  * The caller must have set al->ctx.
827  */
sample_parse_expr(char ** str,int * idx,const char * file,int line,char ** err_msg,struct arg_list * al)828 struct sample_expr *sample_parse_expr(char **str, int *idx, const char *file, int line, char **err_msg, struct arg_list *al)
829 {
830 	const char *begw; /* beginning of word */
831 	const char *endw; /* end of word */
832 	const char *endt; /* end of term */
833 	struct sample_expr *expr;
834 	struct sample_fetch *fetch;
835 	struct sample_conv *conv;
836 	unsigned long prev_type;
837 	char *fkw = NULL;
838 	char *ckw = NULL;
839 	int err_arg;
840 
841 	begw = str[*idx];
842 	for (endw = begw; *endw && *endw != '(' && *endw != ','; endw++);
843 
844 	if (endw == begw) {
845 		memprintf(err_msg, "missing fetch method");
846 		goto out_error;
847 	}
848 
849 	/* keep a copy of the current fetch keyword for error reporting */
850 	fkw = my_strndup(begw, endw - begw);
851 
852 	fetch = find_sample_fetch(begw, endw - begw);
853 	if (!fetch) {
854 		memprintf(err_msg, "unknown fetch method '%s'", fkw);
855 		goto out_error;
856 	}
857 
858 	endt = endw;
859 	if (*endt == '(') {
860 		/* look for the end of this term and skip the opening parenthesis */
861 		endt = ++endw;
862 		while (*endt && *endt != ')')
863 			endt++;
864 		if (*endt != ')') {
865 			memprintf(err_msg, "missing closing ')' after arguments to fetch keyword '%s'", fkw);
866 			goto out_error;
867 		}
868 	}
869 
870 	/* At this point, we have :
871 	 *   - begw : beginning of the keyword
872 	 *   - endw : end of the keyword, first character not part of keyword
873 	 *            nor the opening parenthesis (so first character of args
874 	 *            if present).
875 	 *   - endt : end of the term (=endw or last parenthesis if args are present)
876 	 */
877 
878 	if (fetch->out_type >= SMP_TYPES) {
879 		memprintf(err_msg, "returns type of fetch method '%s' is unknown", fkw);
880 		goto out_error;
881 	}
882 	prev_type = fetch->out_type;
883 
884 	expr = calloc(1, sizeof(*expr));
885 	if (!expr)
886 		goto out_error;
887 
888 	LIST_INIT(&(expr->conv_exprs));
889 	expr->fetch = fetch;
890 	expr->arg_p = empty_arg_list;
891 
892 	/* Note that we call the argument parser even with an empty string,
893 	 * this allows it to automatically create entries for mandatory
894 	 * implicit arguments (eg: local proxy name).
895 	 */
896 	al->kw = expr->fetch->kw;
897 	al->conv = NULL;
898 	if (make_arg_list(endw, endt - endw, fetch->arg_mask, &expr->arg_p, err_msg, NULL, &err_arg, al) < 0) {
899 		memprintf(err_msg, "fetch method '%s' : %s", fkw, *err_msg);
900 		goto out_error;
901 	}
902 
903 	if (!expr->arg_p) {
904 		expr->arg_p = empty_arg_list;
905 	}
906 	else if (fetch->val_args && !fetch->val_args(expr->arg_p, err_msg)) {
907 		memprintf(err_msg, "invalid args in fetch method '%s' : %s", fkw, *err_msg);
908 		goto out_error;
909 	}
910 
911 	/* Now process the converters if any. We have two supported syntaxes
912 	 * for the converters, which can be combined :
913 	 *  - comma-delimited list of converters just after the keyword and args ;
914 	 *  - one converter per keyword
915 	 * The combination allows to have each keyword being a comma-delimited
916 	 * series of converters.
917 	 *
918 	 * We want to process the former first, then the latter. For this we start
919 	 * from the beginning of the supposed place in the exiting conv chain, which
920 	 * starts at the last comma (endt).
921 	 */
922 
923 	while (1) {
924 		struct sample_conv_expr *conv_expr;
925 		int err_arg;
926 		int argcnt;
927 
928 		if (*endt == ')') /* skip last closing parenthesis */
929 			endt++;
930 
931 		if (*endt && *endt != ',') {
932 			if (ckw)
933 				memprintf(err_msg, "missing comma after converter '%s'", ckw);
934 			else
935 				memprintf(err_msg, "missing comma after fetch keyword '%s'", fkw);
936 			goto out_error;
937 		}
938 
939 		while (*endt == ',') /* then trailing commas */
940 			endt++;
941 
942 		begw = endt; /* start of converter */
943 
944 		if (!*begw) {
945 			/* none ? skip to next string */
946 			(*idx)++;
947 			begw = str[*idx];
948 			if (!begw || !*begw)
949 				break;
950 		}
951 
952 		for (endw = begw; *endw && *endw != '(' && *endw != ','; endw++);
953 
954 		free(ckw);
955 		ckw = my_strndup(begw, endw - begw);
956 
957 		conv = find_sample_conv(begw, endw - begw);
958 		if (!conv) {
959 			/* we found an isolated keyword that we don't know, it's not ours */
960 			if (begw == str[*idx])
961 				break;
962 			memprintf(err_msg, "unknown converter '%s'", ckw);
963 			goto out_error;
964 		}
965 
966 		endt = endw;
967 		if (*endt == '(') {
968 			/* look for the end of this term */
969 			endt = ++endw;
970 			while (*endt && *endt != ')')
971 				endt++;
972 			if (*endt != ')') {
973 				memprintf(err_msg, "syntax error: missing ')' after converter '%s'", ckw);
974 				goto out_error;
975 			}
976 		}
977 
978 		if (conv->in_type >= SMP_TYPES || conv->out_type >= SMP_TYPES) {
979 			memprintf(err_msg, "returns type of converter '%s' is unknown", ckw);
980 			goto out_error;
981 		}
982 
983 		/* If impossible type conversion */
984 		if (!sample_casts[prev_type][conv->in_type]) {
985 			memprintf(err_msg, "converter '%s' cannot be applied", ckw);
986 			goto out_error;
987 		}
988 
989 		prev_type = conv->out_type;
990 		conv_expr = calloc(1, sizeof(*conv_expr));
991 		if (!conv_expr)
992 			goto out_error;
993 
994 		LIST_ADDQ(&(expr->conv_exprs), &(conv_expr->list));
995 		conv_expr->conv = conv;
996 
997 		al->kw = expr->fetch->kw;
998 		al->conv = conv_expr->conv->kw;
999 		argcnt = make_arg_list(endw, endt - endw, conv->arg_mask, &conv_expr->arg_p, err_msg, NULL, &err_arg, al);
1000 		if (argcnt < 0) {
1001 			memprintf(err_msg, "invalid arg %d in converter '%s' : %s", err_arg+1, ckw, *err_msg);
1002 			goto out_error;
1003 		}
1004 
1005 		if (argcnt && !conv->arg_mask) {
1006 			memprintf(err_msg, "converter '%s' does not support any args", ckw);
1007 			goto out_error;
1008 		}
1009 
1010 		if (!conv_expr->arg_p)
1011 			conv_expr->arg_p = empty_arg_list;
1012 
1013 		if (conv->val_args && !conv->val_args(conv_expr->arg_p, conv, file, line, err_msg)) {
1014 			memprintf(err_msg, "invalid args in converter '%s' : %s", ckw, *err_msg);
1015 			goto out_error;
1016 		}
1017 	}
1018 
1019  out:
1020 	free(fkw);
1021 	free(ckw);
1022 	return expr;
1023 
1024 out_error:
1025 	/* TODO: prune_sample_expr(expr); */
1026 	expr = NULL;
1027 	goto out;
1028 }
1029 
1030 /*
1031  * Process a fetch + format conversion of defined by the sample expression <expr>
1032  * on request or response considering the <opt> parameter.
1033  * Returns a pointer on a typed sample structure containing the result or NULL if
1034  * sample is not found or when format conversion failed.
1035  *  If <p> is not null, function returns results in structure pointed by <p>.
1036  *  If <p> is null, functions returns a pointer on a static sample structure.
1037  *
1038  * Note: the fetch functions are required to properly set the return type. The
1039  * conversion functions must do so too. However the cast functions do not need
1040  * to since they're made to cast mutiple types according to what is required.
1041  *
1042  * The caller may indicate in <opt> if it considers the result final or not.
1043  * The caller needs to check the SMP_F_MAY_CHANGE flag in p->flags to verify
1044  * if the result is stable or not, according to the following table :
1045  *
1046  * return MAY_CHANGE FINAL   Meaning for the sample
1047  *  NULL      0        *     Not present and will never be (eg: header)
1048  *  NULL      1        0     Not present yet, could change (eg: POST param)
1049  *  NULL      1        1     Not present yet, will not change anymore
1050  *   smp      0        *     Present and will not change (eg: header)
1051  *   smp      1        0     Present, may change (eg: request length)
1052  *   smp      1        1     Present, last known value (eg: request length)
1053  */
sample_process(struct proxy * px,struct session * sess,struct stream * strm,unsigned int opt,struct sample_expr * expr,struct sample * p)1054 struct sample *sample_process(struct proxy *px, struct session *sess,
1055                               struct stream *strm, unsigned int opt,
1056                               struct sample_expr *expr, struct sample *p)
1057 {
1058 	struct sample_conv_expr *conv_expr;
1059 
1060 	if (p == NULL) {
1061 		p = &temp_smp;
1062 		memset(p, 0, sizeof(*p));
1063 	}
1064 
1065 	smp_set_owner(p, px, sess, strm, opt);
1066 	if (!expr->fetch->process(expr->arg_p, p, expr->fetch->kw, expr->fetch->private))
1067 		return NULL;
1068 
1069 	list_for_each_entry(conv_expr, &expr->conv_exprs, list) {
1070 		/* we want to ensure that p->type can be casted into
1071 		 * conv_expr->conv->in_type. We have 3 possibilities :
1072 		 *  - NULL   => not castable.
1073 		 *  - c_none => nothing to do (let's optimize it)
1074 		 *  - other  => apply cast and prepare to fail
1075 		 */
1076 		if (!sample_casts[p->data.type][conv_expr->conv->in_type])
1077 			return NULL;
1078 
1079 		if (sample_casts[p->data.type][conv_expr->conv->in_type] != c_none &&
1080 		    !sample_casts[p->data.type][conv_expr->conv->in_type](p))
1081 			return NULL;
1082 
1083 		/* OK cast succeeded */
1084 
1085 		if (!conv_expr->conv->process(conv_expr->arg_p, p, conv_expr->conv->private))
1086 			return NULL;
1087 	}
1088 	return p;
1089 }
1090 
1091 /*
1092  * Resolve all remaining arguments in proxy <p>. Returns the number of
1093  * errors or 0 if everything is fine.
1094  */
smp_resolve_args(struct proxy * p)1095 int smp_resolve_args(struct proxy *p)
1096 {
1097 	struct arg_list *cur, *bak;
1098 	const char *ctx, *where;
1099 	const char *conv_ctx, *conv_pre, *conv_pos;
1100 	struct userlist *ul;
1101 	struct my_regex *reg;
1102 	struct arg *arg;
1103 	int cfgerr = 0;
1104 	int rflags;
1105 
1106 	list_for_each_entry_safe(cur, bak, &p->conf.args.list, list) {
1107 		struct proxy *px;
1108 		struct server *srv;
1109 		struct stktable *t;
1110 		char *pname, *sname, *stktname;
1111 		char *err;
1112 
1113 		arg = cur->arg;
1114 
1115 		/* prepare output messages */
1116 		conv_pre = conv_pos = conv_ctx = "";
1117 		if (cur->conv) {
1118 			conv_ctx = cur->conv;
1119 			conv_pre = "conversion keyword '";
1120 			conv_pos = "' for ";
1121 		}
1122 
1123 		where = "in";
1124 		ctx = "sample fetch keyword";
1125 		switch (cur->ctx) {
1126 		case ARGC_STK:   where = "in stick rule in"; break;
1127 		case ARGC_TRK:   where = "in tracking rule in"; break;
1128 		case ARGC_LOG:   where = "in log-format string in"; break;
1129 		case ARGC_LOGSD: where = "in log-format-sd string in"; break;
1130 		case ARGC_HRQ:   where = "in http-request header format string in"; break;
1131 		case ARGC_HRS:   where = "in http-response header format string in"; break;
1132 		case ARGC_UIF:   where = "in unique-id-format string in"; break;
1133 		case ARGC_RDR:   where = "in redirect format string in"; break;
1134 		case ARGC_CAP:   where = "in capture rule in"; break;
1135 		case ARGC_ACL:   ctx = "ACL keyword"; break;
1136 		case ARGC_SRV:   where = "in server directive in"; break;
1137 		case ARGC_SPOE:  where = "in spoe-message directive in"; break;
1138 		}
1139 
1140 		/* set a few default settings */
1141 		px = p;
1142 		pname = p->id;
1143 
1144 		switch (arg->type) {
1145 		case ARGT_SRV:
1146 			if (!arg->data.str.data) {
1147 				ha_alert("parsing [%s:%d] : missing server name in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1148 					 cur->file, cur->line,
1149 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1150 				cfgerr++;
1151 				continue;
1152 			}
1153 
1154 			/* we support two formats : "bck/srv" and "srv" */
1155 			sname = strrchr(arg->data.str.area, '/');
1156 
1157 			if (sname) {
1158 				*sname++ = '\0';
1159 				pname = arg->data.str.area;
1160 
1161 				px = proxy_be_by_name(pname);
1162 				if (!px) {
1163 					ha_alert("parsing [%s:%d] : unable to find proxy '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1164 						 cur->file, cur->line, pname,
1165 						 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1166 					cfgerr++;
1167 					break;
1168 				}
1169 			}
1170 			else
1171 				sname = arg->data.str.area;
1172 
1173 			srv = findserver(px, sname);
1174 			if (!srv) {
1175 				ha_alert("parsing [%s:%d] : unable to find server '%s' in proxy '%s', referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1176 					 cur->file, cur->line, sname, pname,
1177 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1178 				cfgerr++;
1179 				break;
1180 			}
1181 
1182 			free(arg->data.str.area);
1183 			arg->data.str.area = NULL;
1184 			arg->unresolved = 0;
1185 			arg->data.srv = srv;
1186 			break;
1187 
1188 		case ARGT_FE:
1189 			if (arg->data.str.data) {
1190 				pname = arg->data.str.area;
1191 				px = proxy_fe_by_name(pname);
1192 			}
1193 
1194 			if (!px) {
1195 				ha_alert("parsing [%s:%d] : unable to find frontend '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1196 					 cur->file, cur->line, pname,
1197 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1198 				cfgerr++;
1199 				break;
1200 			}
1201 
1202 			if (!(px->cap & PR_CAP_FE)) {
1203 				ha_alert("parsing [%s:%d] : proxy '%s', referenced in arg %d of %s%s%s%s '%s' %s proxy '%s', has not frontend capability.\n",
1204 					 cur->file, cur->line, pname,
1205 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1206 				cfgerr++;
1207 				break;
1208 			}
1209 
1210 			free(arg->data.str.area);
1211 			arg->data.str.area = NULL;
1212 			arg->unresolved = 0;
1213 			arg->data.prx = px;
1214 			break;
1215 
1216 		case ARGT_BE:
1217 			if (arg->data.str.data) {
1218 				pname = arg->data.str.area;
1219 				px = proxy_be_by_name(pname);
1220 			}
1221 
1222 			if (!px) {
1223 				ha_alert("parsing [%s:%d] : unable to find backend '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1224 					 cur->file, cur->line, pname,
1225 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1226 				cfgerr++;
1227 				break;
1228 			}
1229 
1230 			if (!(px->cap & PR_CAP_BE)) {
1231 				ha_alert("parsing [%s:%d] : proxy '%s', referenced in arg %d of %s%s%s%s '%s' %s proxy '%s', has not backend capability.\n",
1232 					 cur->file, cur->line, pname,
1233 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1234 				cfgerr++;
1235 				break;
1236 			}
1237 
1238 			free(arg->data.str.area);
1239 			arg->data.str.area = NULL;
1240 			arg->unresolved = 0;
1241 			arg->data.prx = px;
1242 			break;
1243 
1244 		case ARGT_TAB:
1245 			if (arg->data.str.data)
1246 				stktname = arg->data.str.area;
1247 			else
1248 				stktname = px->id;
1249 
1250 			t = stktable_find_by_name(stktname);
1251 			if (!t) {
1252 				ha_alert("parsing [%s:%d] : unable to find table '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1253 					 cur->file, cur->line, stktname,
1254 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1255 				cfgerr++;
1256 				break;
1257 			}
1258 
1259 			if (!t->size) {
1260 				ha_alert("parsing [%s:%d] : no table in proxy '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1261 					 cur->file, cur->line, stktname,
1262 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1263 				cfgerr++;
1264 				break;
1265 			}
1266 
1267 			if (t->proxy && (p->bind_proc & ~t->proxy->bind_proc)) {
1268 				ha_alert("parsing [%s:%d] : stick-table '%s' not present on all processes covered by proxy '%s'.\n",
1269 					 cur->file, cur->line, t->proxy->id, p->id);
1270 				cfgerr++;
1271 				break;
1272 			}
1273 
1274 			if (!in_proxies_list(t->proxies_list, p)) {
1275 				p->next_stkt_ref = t->proxies_list;
1276 				t->proxies_list = p;
1277 			}
1278 
1279 			free(arg->data.str.area);
1280 			arg->data.str.area = NULL;
1281 			arg->unresolved = 0;
1282 			arg->data.t = t;
1283 			break;
1284 
1285 		case ARGT_USR:
1286 			if (!arg->data.str.data) {
1287 				ha_alert("parsing [%s:%d] : missing userlist name in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1288 					 cur->file, cur->line,
1289 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1290 				cfgerr++;
1291 				break;
1292 			}
1293 
1294 			if (p->uri_auth && p->uri_auth->userlist &&
1295 			    !strcmp(p->uri_auth->userlist->name, arg->data.str.area))
1296 				ul = p->uri_auth->userlist;
1297 			else
1298 				ul = auth_find_userlist(arg->data.str.area);
1299 
1300 			if (!ul) {
1301 				ha_alert("parsing [%s:%d] : unable to find userlist '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1302 					 cur->file, cur->line,
1303 					 arg->data.str.area,
1304 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1305 				cfgerr++;
1306 				break;
1307 			}
1308 
1309 			free(arg->data.str.area);
1310 			arg->data.str.area = NULL;
1311 			arg->unresolved = 0;
1312 			arg->data.usr = ul;
1313 			break;
1314 
1315 		case ARGT_REG:
1316 			if (!arg->data.str.data) {
1317 				ha_alert("parsing [%s:%d] : missing regex in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1318 					 cur->file, cur->line,
1319 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1320 				cfgerr++;
1321 				continue;
1322 			}
1323 
1324 			rflags = 0;
1325 			rflags |= (arg->type_flags & ARGF_REG_ICASE) ? REG_ICASE : 0;
1326 			err = NULL;
1327 
1328 			if (!(reg = regex_comp(arg->data.str.area, !(rflags & REG_ICASE), 1 /* capture substr */, &err))) {
1329 				ha_alert("parsing [%s:%d] : error in regex '%s' in arg %d of %s%s%s%s '%s' %s proxy '%s' : %s.\n",
1330 					 cur->file, cur->line,
1331 					 arg->data.str.area,
1332 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id, err);
1333 				cfgerr++;
1334 				continue;
1335 			}
1336 
1337 			free(arg->data.str.area);
1338 			arg->data.str.area = NULL;
1339 			arg->unresolved = 0;
1340 			arg->data.reg = reg;
1341 			break;
1342 
1343 
1344 		}
1345 
1346 		LIST_DEL(&cur->list);
1347 		free(cur);
1348 	} /* end of args processing */
1349 
1350 	return cfgerr;
1351 }
1352 
1353 /*
1354  * Process a fetch + format conversion as defined by the sample expression
1355  * <expr> on request or response considering the <opt> parameter. The output is
1356  * not explicitly set to <smp_type>, but shall be compatible with it as
1357  * specified by 'sample_casts' table. If a stable sample can be fetched, or an
1358  * unstable one when <opt> contains SMP_OPT_FINAL, the sample is converted and
1359  * returned without the SMP_F_MAY_CHANGE flag. If an unstable sample is found
1360  * and <opt> does not contain SMP_OPT_FINAL, then the sample is returned as-is
1361  * with its SMP_F_MAY_CHANGE flag so that the caller can check it and decide to
1362  * take actions (eg: wait longer). If a sample could not be found or could not
1363  * be converted, NULL is returned. The caller MUST NOT use the sample if the
1364  * SMP_F_MAY_CHANGE flag is present, as it is used only as a hint that there is
1365  * still hope to get it after waiting longer, and is not converted to string.
1366  * The possible output combinations are the following :
1367  *
1368  * return MAY_CHANGE FINAL   Meaning for the sample
1369  *  NULL      *        *     Not present and will never be (eg: header)
1370  *   smp      0        *     Final value converted (eg: header)
1371  *   smp      1        0     Not present yet, may appear later (eg: header)
1372  *   smp      1        1     never happens (either flag is cleared on output)
1373  */
sample_fetch_as_type(struct proxy * px,struct session * sess,struct stream * strm,unsigned int opt,struct sample_expr * expr,int smp_type)1374 struct sample *sample_fetch_as_type(struct proxy *px, struct session *sess,
1375                                    struct stream *strm, unsigned int opt,
1376                                    struct sample_expr *expr, int smp_type)
1377 {
1378 	struct sample *smp = &temp_smp;
1379 
1380 	memset(smp, 0, sizeof(*smp));
1381 
1382 	if (!sample_process(px, sess, strm, opt, expr, smp)) {
1383 		if ((smp->flags & SMP_F_MAY_CHANGE) && !(opt & SMP_OPT_FINAL))
1384 			return smp;
1385 		return NULL;
1386 	}
1387 
1388 	if (!sample_casts[smp->data.type][smp_type])
1389 		return NULL;
1390 
1391 	if (!sample_casts[smp->data.type][smp_type](smp))
1392 		return NULL;
1393 
1394 	smp->flags &= ~SMP_F_MAY_CHANGE;
1395 	return smp;
1396 }
1397 
release_sample_arg(struct arg * p)1398 static void release_sample_arg(struct arg *p)
1399 {
1400 	struct arg *p_back = p;
1401 
1402 	if (!p)
1403 		return;
1404 
1405 	while (p->type != ARGT_STOP) {
1406 		if (p->type == ARGT_STR || p->unresolved) {
1407 			free(p->data.str.area);
1408 			p->data.str.area = NULL;
1409 			p->unresolved = 0;
1410 		}
1411 		else if (p->type == ARGT_REG) {
1412 			regex_free(p->data.reg);
1413 			p->data.reg = NULL;
1414 		}
1415 		p++;
1416 	}
1417 
1418 	if (p_back != empty_arg_list)
1419 		free(p_back);
1420 }
1421 
release_sample_expr(struct sample_expr * expr)1422 void release_sample_expr(struct sample_expr *expr)
1423 {
1424 	struct sample_conv_expr *conv_expr, *conv_exprb;
1425 
1426 	if (!expr)
1427 		return;
1428 
1429 	list_for_each_entry_safe(conv_expr, conv_exprb, &expr->conv_exprs, list)
1430 		release_sample_arg(conv_expr->arg_p);
1431 	release_sample_arg(expr->arg_p);
1432 	free(expr);
1433 }
1434 
1435 /*****************************************************************/
1436 /*    Sample format convert functions                            */
1437 /*    These functions set the data type on return.               */
1438 /*****************************************************************/
1439 
sample_conv_debug(const struct arg * arg_p,struct sample * smp,void * private)1440 static int sample_conv_debug(const struct arg *arg_p, struct sample *smp, void *private)
1441 {
1442 	int i;
1443 	struct sample tmp;
1444 	struct buffer *buf;
1445 	struct sink *sink;
1446 	struct ist line;
1447 	char *pfx;
1448 
1449 	buf = alloc_trash_chunk();
1450 	if (!buf)
1451 		goto end;
1452 
1453 	sink = (struct sink *)arg_p[1].data.str.area;
1454 	BUG_ON(!sink);
1455 
1456 	pfx = arg_p[0].data.str.area;
1457 	BUG_ON(!pfx);
1458 
1459 	chunk_printf(buf, "[debug] %s: type=%s ", pfx, smp_to_type[smp->data.type]);
1460 	if (!sample_casts[smp->data.type][SMP_T_STR])
1461 		goto nocast;
1462 
1463 	/* Copy sample fetch. This puts the sample as const, the
1464 	 * cast will copy data if a transformation is required.
1465 	 */
1466 	memcpy(&tmp, smp, sizeof(struct sample));
1467 	tmp.flags = SMP_F_CONST;
1468 
1469 	if (!sample_casts[smp->data.type][SMP_T_STR](&tmp))
1470 		goto nocast;
1471 
1472 	/* Display the displayable chars*. */
1473 	b_putchr(buf, '<');
1474 	for (i = 0; i < tmp.data.u.str.data; i++) {
1475 		if (isprint(tmp.data.u.str.area[i]))
1476 			b_putchr(buf, tmp.data.u.str.area[i]);
1477 		else
1478 			b_putchr(buf, '.');
1479 	}
1480 	b_putchr(buf, '>');
1481 
1482  done:
1483 	line = ist2(buf->area, buf->data);
1484 	sink_write(sink, &line, 1);
1485  end:
1486 	free_trash_chunk(buf);
1487 	return 1;
1488  nocast:
1489 	chunk_appendf(buf, "(undisplayable)");
1490 	goto done;
1491 }
1492 
1493 // This function checks the "debug" converter's arguments.
smp_check_debug(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)1494 static int smp_check_debug(struct arg *args, struct sample_conv *conv,
1495                            const char *file, int line, char **err)
1496 {
1497 	const char *name = "buf0";
1498 	struct sink *sink = NULL;
1499 
1500 	if (args[0].type != ARGT_STR) {
1501 		/* optional prefix */
1502 		args[0].data.str.area = "";
1503 		args[0].data.str.data = 0;
1504 	}
1505 
1506 	if (args[1].type == ARGT_STR)
1507 		name = args[1].data.str.area;
1508 
1509 	sink = sink_find(name);
1510 	if (!sink) {
1511 		memprintf(err, "No such sink '%s'", name);
1512 		return 0;
1513 	}
1514 
1515 	args[1].data.str.area = (char *)sink;
1516 	args[1].data.str.data = 0; // that's not a string anymore
1517 	return 1;
1518 }
1519 
sample_conv_base642bin(const struct arg * arg_p,struct sample * smp,void * private)1520 static int sample_conv_base642bin(const struct arg *arg_p, struct sample *smp, void *private)
1521 {
1522 	struct buffer *trash = get_trash_chunk();
1523 	int bin_len;
1524 
1525 	trash->data = 0;
1526 	bin_len = base64dec(smp->data.u.str.area, smp->data.u.str.data,
1527 			    trash->area, trash->size);
1528 	if (bin_len < 0)
1529 		return 0;
1530 
1531 	trash->data = bin_len;
1532 	smp->data.u.str = *trash;
1533 	smp->data.type = SMP_T_BIN;
1534 	smp->flags &= ~SMP_F_CONST;
1535 	return 1;
1536 }
1537 
sample_conv_bin2base64(const struct arg * arg_p,struct sample * smp,void * private)1538 static int sample_conv_bin2base64(const struct arg *arg_p, struct sample *smp, void *private)
1539 {
1540 	struct buffer *trash = get_trash_chunk();
1541 	int b64_len;
1542 
1543 	trash->data = 0;
1544 	b64_len = a2base64(smp->data.u.str.area, smp->data.u.str.data,
1545 			   trash->area, trash->size);
1546 	if (b64_len < 0)
1547 		return 0;
1548 
1549 	trash->data = b64_len;
1550 	smp->data.u.str = *trash;
1551 	smp->data.type = SMP_T_STR;
1552 	smp->flags &= ~SMP_F_CONST;
1553 	return 1;
1554 }
1555 
sample_conv_sha1(const struct arg * arg_p,struct sample * smp,void * private)1556 static int sample_conv_sha1(const struct arg *arg_p, struct sample *smp, void *private)
1557 {
1558 	blk_SHA_CTX ctx;
1559 	struct buffer *trash = get_trash_chunk();
1560 
1561 	memset(&ctx, 0, sizeof(ctx));
1562 
1563 	blk_SHA1_Init(&ctx);
1564 	blk_SHA1_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1565 	blk_SHA1_Final((unsigned char *) trash->area, &ctx);
1566 
1567 	trash->data = 20;
1568 	smp->data.u.str = *trash;
1569 	smp->data.type = SMP_T_BIN;
1570 	smp->flags &= ~SMP_F_CONST;
1571 	return 1;
1572 }
1573 
1574 #ifdef USE_OPENSSL
smp_check_sha2(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)1575 static int smp_check_sha2(struct arg *args, struct sample_conv *conv,
1576                           const char *file, int line, char **err)
1577 {
1578 	if (args[0].type == ARGT_STOP)
1579 		return 1;
1580 	if (args[0].type != ARGT_SINT) {
1581 		memprintf(err, "Invalid type '%s'", arg_type_names[args[0].type]);
1582 		return 0;
1583 	}
1584 
1585 	switch (args[0].data.sint) {
1586 		case 224:
1587 		case 256:
1588 		case 384:
1589 		case 512:
1590 			/* this is okay */
1591 			return 1;
1592 		default:
1593 			memprintf(err, "Unsupported number of bits: '%lld'", args[0].data.sint);
1594 			return 0;
1595 	}
1596 }
1597 
sample_conv_sha2(const struct arg * arg_p,struct sample * smp,void * private)1598 static int sample_conv_sha2(const struct arg *arg_p, struct sample *smp, void *private)
1599 {
1600 	struct buffer *trash = get_trash_chunk();
1601 	int bits = 256;
1602 	if (arg_p && arg_p->data.sint)
1603 		bits = arg_p->data.sint;
1604 
1605 	switch (bits) {
1606 	case 224: {
1607 		SHA256_CTX ctx;
1608 
1609 		memset(&ctx, 0, sizeof(ctx));
1610 
1611 		SHA224_Init(&ctx);
1612 		SHA224_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1613 		SHA224_Final((unsigned char *) trash->area, &ctx);
1614 		trash->data = SHA224_DIGEST_LENGTH;
1615 		break;
1616 	}
1617 	case 256: {
1618 		SHA256_CTX ctx;
1619 
1620 		memset(&ctx, 0, sizeof(ctx));
1621 
1622 		SHA256_Init(&ctx);
1623 		SHA256_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1624 		SHA256_Final((unsigned char *) trash->area, &ctx);
1625 		trash->data = SHA256_DIGEST_LENGTH;
1626 		break;
1627 	}
1628 	case 384: {
1629 		SHA512_CTX ctx;
1630 
1631 		memset(&ctx, 0, sizeof(ctx));
1632 
1633 		SHA384_Init(&ctx);
1634 		SHA384_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1635 		SHA384_Final((unsigned char *) trash->area, &ctx);
1636 		trash->data = SHA384_DIGEST_LENGTH;
1637 		break;
1638 	}
1639 	case 512: {
1640 		SHA512_CTX ctx;
1641 
1642 		memset(&ctx, 0, sizeof(ctx));
1643 
1644 		SHA512_Init(&ctx);
1645 		SHA512_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1646 		SHA512_Final((unsigned char *) trash->area, &ctx);
1647 		trash->data = SHA512_DIGEST_LENGTH;
1648 		break;
1649 	}
1650 	default:
1651 		return 0;
1652 	}
1653 
1654 	smp->data.u.str = *trash;
1655 	smp->data.type = SMP_T_BIN;
1656 	smp->flags &= ~SMP_F_CONST;
1657 	return 1;
1658 }
1659 #endif
1660 
sample_conv_bin2hex(const struct arg * arg_p,struct sample * smp,void * private)1661 static int sample_conv_bin2hex(const struct arg *arg_p, struct sample *smp, void *private)
1662 {
1663 	struct buffer *trash = get_trash_chunk();
1664 	unsigned char c;
1665 	int ptr = 0;
1666 
1667 	trash->data = 0;
1668 	while (ptr < smp->data.u.str.data && trash->data <= trash->size - 2) {
1669 		c = smp->data.u.str.area[ptr++];
1670 		trash->area[trash->data++] = hextab[(c >> 4) & 0xF];
1671 		trash->area[trash->data++] = hextab[c & 0xF];
1672 	}
1673 	smp->data.u.str = *trash;
1674 	smp->data.type = SMP_T_STR;
1675 	smp->flags &= ~SMP_F_CONST;
1676 	return 1;
1677 }
1678 
sample_conv_hex2int(const struct arg * arg_p,struct sample * smp,void * private)1679 static int sample_conv_hex2int(const struct arg *arg_p, struct sample *smp, void *private)
1680 {
1681 	long long int n = 0;
1682 	int i, c;
1683 
1684 	for (i = 0; i < smp->data.u.str.data; i++) {
1685 		if ((c = hex2i(smp->data.u.str.area[i])) < 0)
1686 			return 0;
1687 		n = (n << 4) + c;
1688 	}
1689 
1690 	smp->data.u.sint = n;
1691 	smp->data.type = SMP_T_SINT;
1692 	smp->flags &= ~SMP_F_CONST;
1693 	return 1;
1694 }
1695 
1696 /* hashes the binary input into a 32-bit unsigned int */
sample_conv_djb2(const struct arg * arg_p,struct sample * smp,void * private)1697 static int sample_conv_djb2(const struct arg *arg_p, struct sample *smp, void *private)
1698 {
1699 	smp->data.u.sint = hash_djb2(smp->data.u.str.area,
1700 				     smp->data.u.str.data);
1701 	if (arg_p && arg_p->data.sint)
1702 		smp->data.u.sint = full_hash(smp->data.u.sint);
1703 	smp->data.type = SMP_T_SINT;
1704 	return 1;
1705 }
1706 
sample_conv_length(const struct arg * arg_p,struct sample * smp,void * private)1707 static int sample_conv_length(const struct arg *arg_p, struct sample *smp, void *private)
1708 {
1709 	int i = smp->data.u.str.data;
1710 	smp->data.u.sint = i;
1711 	smp->data.type = SMP_T_SINT;
1712 	return 1;
1713 }
1714 
1715 
sample_conv_str2lower(const struct arg * arg_p,struct sample * smp,void * private)1716 static int sample_conv_str2lower(const struct arg *arg_p, struct sample *smp, void *private)
1717 {
1718 	int i;
1719 
1720 	if (!smp_make_rw(smp))
1721 		return 0;
1722 
1723 	for (i = 0; i < smp->data.u.str.data; i++) {
1724 		if ((smp->data.u.str.area[i] >= 'A') && (smp->data.u.str.area[i] <= 'Z'))
1725 			smp->data.u.str.area[i] += 'a' - 'A';
1726 	}
1727 	return 1;
1728 }
1729 
sample_conv_str2upper(const struct arg * arg_p,struct sample * smp,void * private)1730 static int sample_conv_str2upper(const struct arg *arg_p, struct sample *smp, void *private)
1731 {
1732 	int i;
1733 
1734 	if (!smp_make_rw(smp))
1735 		return 0;
1736 
1737 	for (i = 0; i < smp->data.u.str.data; i++) {
1738 		if ((smp->data.u.str.area[i] >= 'a') && (smp->data.u.str.area[i] <= 'z'))
1739 			smp->data.u.str.area[i] += 'A' - 'a';
1740 	}
1741 	return 1;
1742 }
1743 
1744 /* takes the IPv4 mask in args[0] and an optional IPv6 mask in args[1] */
sample_conv_ipmask(const struct arg * args,struct sample * smp,void * private)1745 static int sample_conv_ipmask(const struct arg *args, struct sample *smp, void *private)
1746 {
1747 	/* Attempt to convert to IPv4 to apply the correct mask. */
1748 	c_ipv62ip(smp);
1749 
1750 	if (smp->data.type == SMP_T_IPV4) {
1751 		smp->data.u.ipv4.s_addr &= args[0].data.ipv4.s_addr;
1752 		smp->data.type = SMP_T_IPV4;
1753 	}
1754 	else if (smp->data.type == SMP_T_IPV6) {
1755 		/* IPv6 cannot be converted without an IPv6 mask. */
1756 		if (args[1].type != ARGT_IPV6)
1757 			return 0;
1758 
1759 		*(uint32_t*)&smp->data.u.ipv6.s6_addr[0]  &= *(uint32_t*)&args[1].data.ipv6.s6_addr[0];
1760 		*(uint32_t*)&smp->data.u.ipv6.s6_addr[4]  &= *(uint32_t*)&args[1].data.ipv6.s6_addr[4];
1761 		*(uint32_t*)&smp->data.u.ipv6.s6_addr[8]  &= *(uint32_t*)&args[1].data.ipv6.s6_addr[8];
1762 		*(uint32_t*)&smp->data.u.ipv6.s6_addr[12] &= *(uint32_t*)&args[1].data.ipv6.s6_addr[12];
1763 		smp->data.type = SMP_T_IPV6;
1764 	}
1765 
1766 	return 1;
1767 }
1768 
1769 /* takes an UINT value on input supposed to represent the time since EPOCH,
1770  * adds an optional offset found in args[1] and emits a string representing
1771  * the local time in the format specified in args[1] using strftime().
1772  */
sample_conv_ltime(const struct arg * args,struct sample * smp,void * private)1773 static int sample_conv_ltime(const struct arg *args, struct sample *smp, void *private)
1774 {
1775 	struct buffer *temp;
1776 	/* With high numbers, the date returned can be negative, the 55 bits mask prevent this. */
1777 	time_t curr_date = smp->data.u.sint & 0x007fffffffffffffLL;
1778 	struct tm *tm;
1779 
1780 	/* add offset */
1781 	if (args[1].type == ARGT_SINT)
1782 		curr_date += args[1].data.sint;
1783 
1784 	tm = localtime(&curr_date);
1785 	if (!tm)
1786 		return 0;
1787 	temp = get_trash_chunk();
1788 	temp->data = strftime(temp->area, temp->size, args[0].data.str.area,
1789 			      tm);
1790 	smp->data.u.str = *temp;
1791 	smp->data.type = SMP_T_STR;
1792 	return 1;
1793 }
1794 
1795 /* hashes the binary input into a 32-bit unsigned int */
sample_conv_sdbm(const struct arg * arg_p,struct sample * smp,void * private)1796 static int sample_conv_sdbm(const struct arg *arg_p, struct sample *smp, void *private)
1797 {
1798 	smp->data.u.sint = hash_sdbm(smp->data.u.str.area,
1799 				     smp->data.u.str.data);
1800 	if (arg_p && arg_p->data.sint)
1801 		smp->data.u.sint = full_hash(smp->data.u.sint);
1802 	smp->data.type = SMP_T_SINT;
1803 	return 1;
1804 }
1805 
1806 /* takes an UINT value on input supposed to represent the time since EPOCH,
1807  * adds an optional offset found in args[1] and emits a string representing
1808  * the UTC date in the format specified in args[1] using strftime().
1809  */
sample_conv_utime(const struct arg * args,struct sample * smp,void * private)1810 static int sample_conv_utime(const struct arg *args, struct sample *smp, void *private)
1811 {
1812 	struct buffer *temp;
1813 	/* With high numbers, the date returned can be negative, the 55 bits mask prevent this. */
1814 	time_t curr_date = smp->data.u.sint & 0x007fffffffffffffLL;
1815 	struct tm *tm;
1816 
1817 	/* add offset */
1818 	if (args[1].type == ARGT_SINT)
1819 		curr_date += args[1].data.sint;
1820 
1821 	tm = gmtime(&curr_date);
1822 	if (!tm)
1823 		return 0;
1824 	temp = get_trash_chunk();
1825 	temp->data = strftime(temp->area, temp->size, args[0].data.str.area,
1826 			      tm);
1827 	smp->data.u.str = *temp;
1828 	smp->data.type = SMP_T_STR;
1829 	return 1;
1830 }
1831 
1832 /* hashes the binary input into a 32-bit unsigned int */
sample_conv_wt6(const struct arg * arg_p,struct sample * smp,void * private)1833 static int sample_conv_wt6(const struct arg *arg_p, struct sample *smp, void *private)
1834 {
1835 	smp->data.u.sint = hash_wt6(smp->data.u.str.area,
1836 				    smp->data.u.str.data);
1837 	if (arg_p && arg_p->data.sint)
1838 		smp->data.u.sint = full_hash(smp->data.u.sint);
1839 	smp->data.type = SMP_T_SINT;
1840 	return 1;
1841 }
1842 
1843 /* hashes the binary input into a 32-bit unsigned int using xxh.
1844  * The seed of the hash defaults to 0 but can be changd in argument 1.
1845  */
sample_conv_xxh32(const struct arg * arg_p,struct sample * smp,void * private)1846 static int sample_conv_xxh32(const struct arg *arg_p, struct sample *smp, void *private)
1847 {
1848 	unsigned int seed;
1849 
1850 	if (arg_p && arg_p->data.sint)
1851 		seed = arg_p->data.sint;
1852 	else
1853 		seed = 0;
1854 	smp->data.u.sint = XXH32(smp->data.u.str.area, smp->data.u.str.data,
1855 				 seed);
1856 	smp->data.type = SMP_T_SINT;
1857 	return 1;
1858 }
1859 
1860 /* hashes the binary input into a 64-bit unsigned int using xxh.
1861  * In fact, the function returns a 64 bit unsigned, but the sample
1862  * storage of haproxy only proposes 64-bits signed, so the value is
1863  * cast as signed. This cast doesn't impact the hash repartition.
1864  * The seed of the hash defaults to 0 but can be changd in argument 1.
1865  */
sample_conv_xxh64(const struct arg * arg_p,struct sample * smp,void * private)1866 static int sample_conv_xxh64(const struct arg *arg_p, struct sample *smp, void *private)
1867 {
1868 	unsigned long long int seed;
1869 
1870 	if (arg_p && arg_p->data.sint)
1871 		seed = (unsigned long long int)arg_p->data.sint;
1872 	else
1873 		seed = 0;
1874 	smp->data.u.sint = (long long int)XXH64(smp->data.u.str.area,
1875 						smp->data.u.str.data, seed);
1876 	smp->data.type = SMP_T_SINT;
1877 	return 1;
1878 }
1879 
1880 /* hashes the binary input into a 32-bit unsigned int */
sample_conv_crc32(const struct arg * arg_p,struct sample * smp,void * private)1881 static int sample_conv_crc32(const struct arg *arg_p, struct sample *smp, void *private)
1882 {
1883 	smp->data.u.sint = hash_crc32(smp->data.u.str.area,
1884 				      smp->data.u.str.data);
1885 	if (arg_p && arg_p->data.sint)
1886 		smp->data.u.sint = full_hash(smp->data.u.sint);
1887 	smp->data.type = SMP_T_SINT;
1888 	return 1;
1889 }
1890 
1891 /* hashes the binary input into crc32c (RFC4960, Appendix B [8].) */
sample_conv_crc32c(const struct arg * arg_p,struct sample * smp,void * private)1892 static int sample_conv_crc32c(const struct arg *arg_p, struct sample *smp, void *private)
1893 {
1894 	smp->data.u.sint = hash_crc32c(smp->data.u.str.area,
1895 				       smp->data.u.str.data);
1896 	if (arg_p && arg_p->data.sint)
1897 		smp->data.u.sint = full_hash(smp->data.u.sint);
1898 	smp->data.type = SMP_T_SINT;
1899 	return 1;
1900 }
1901 
1902 /* This function escape special json characters. The returned string can be
1903  * safely set between two '"' and used as json string. The json string is
1904  * defined like this:
1905  *
1906  *    any Unicode character except '"' or '\' or control character
1907  *    \", \\, \/, \b, \f, \n, \r, \t, \u + four-hex-digits
1908  *
1909  * The enum input_type contain all the allowed mode for decoding the input
1910  * string.
1911  */
1912 enum input_type {
1913 	IT_ASCII = 0,
1914 	IT_UTF8,
1915 	IT_UTF8S,
1916 	IT_UTF8P,
1917 	IT_UTF8PS,
1918 };
sample_conv_json_check(struct arg * arg,struct sample_conv * conv,const char * file,int line,char ** err)1919 static int sample_conv_json_check(struct arg *arg, struct sample_conv *conv,
1920                                   const char *file, int line, char **err)
1921 {
1922 	if (!arg) {
1923 		memprintf(err, "Unexpected empty arg list");
1924 		return 0;
1925 	}
1926 
1927 	if (arg->type != ARGT_STR) {
1928 		memprintf(err, "Unexpected arg type");
1929 		return 0;
1930 	}
1931 
1932 	if (strcmp(arg->data.str.area, "") == 0) {
1933 		arg->type = ARGT_SINT;
1934 		arg->data.sint = IT_ASCII;
1935 		return 1;
1936 	}
1937 
1938 	else if (strcmp(arg->data.str.area, "ascii") == 0) {
1939 		arg->type = ARGT_SINT;
1940 		arg->data.sint = IT_ASCII;
1941 		return 1;
1942 	}
1943 
1944 	else if (strcmp(arg->data.str.area, "utf8") == 0) {
1945 		arg->type = ARGT_SINT;
1946 		arg->data.sint = IT_UTF8;
1947 		return 1;
1948 	}
1949 
1950 	else if (strcmp(arg->data.str.area, "utf8s") == 0) {
1951 		arg->type = ARGT_SINT;
1952 		arg->data.sint = IT_UTF8S;
1953 		return 1;
1954 	}
1955 
1956 	else if (strcmp(arg->data.str.area, "utf8p") == 0) {
1957 		arg->type = ARGT_SINT;
1958 		arg->data.sint = IT_UTF8P;
1959 		return 1;
1960 	}
1961 
1962 	else if (strcmp(arg->data.str.area, "utf8ps") == 0) {
1963 		arg->type = ARGT_SINT;
1964 		arg->data.sint = IT_UTF8PS;
1965 		return 1;
1966 	}
1967 
1968 	memprintf(err, "Unexpected input code type. "
1969 	               "Allowed value are 'ascii', 'utf8', 'utf8s', 'utf8p' and 'utf8ps'");
1970 	return 0;
1971 }
1972 
sample_conv_json(const struct arg * arg_p,struct sample * smp,void * private)1973 static int sample_conv_json(const struct arg *arg_p, struct sample *smp, void *private)
1974 {
1975 	struct buffer *temp;
1976 	char _str[7]; /* \u + 4 hex digit + null char for sprintf. */
1977 	const char *str;
1978 	int len;
1979 	enum input_type input_type = IT_ASCII;
1980 	unsigned int c;
1981 	unsigned int ret;
1982 	char *p;
1983 
1984 	if (arg_p)
1985 		input_type = arg_p->data.sint;
1986 
1987 	temp = get_trash_chunk();
1988 	temp->data = 0;
1989 
1990 	p = smp->data.u.str.area;
1991 	while (p < smp->data.u.str.area + smp->data.u.str.data) {
1992 
1993 		if (input_type == IT_ASCII) {
1994 			/* Read input as ASCII. */
1995 			c = *(unsigned char *)p;
1996 			p++;
1997 		}
1998 		else {
1999 			/* Read input as UTF8. */
2000 			ret = utf8_next(p,
2001 					smp->data.u.str.data - ( p - smp->data.u.str.area),
2002 					&c);
2003 			p += utf8_return_length(ret);
2004 
2005 			if (input_type == IT_UTF8 && utf8_return_code(ret) != UTF8_CODE_OK)
2006 					return 0;
2007 			if (input_type == IT_UTF8S && utf8_return_code(ret) != UTF8_CODE_OK)
2008 					continue;
2009 			if (input_type == IT_UTF8P && utf8_return_code(ret) & (UTF8_CODE_INVRANGE|UTF8_CODE_BADSEQ))
2010 					return 0;
2011 			if (input_type == IT_UTF8PS && utf8_return_code(ret) & (UTF8_CODE_INVRANGE|UTF8_CODE_BADSEQ))
2012 					continue;
2013 
2014 			/* Check too big values. */
2015 			if ((unsigned int)c > 0xffff) {
2016 				if (input_type == IT_UTF8 || input_type == IT_UTF8P)
2017 					return 0;
2018 				continue;
2019 			}
2020 		}
2021 
2022 		/* Convert character. */
2023 		if (c == '"') {
2024 			len = 2;
2025 			str = "\\\"";
2026 		}
2027 		else if (c == '\\') {
2028 			len = 2;
2029 			str = "\\\\";
2030 		}
2031 		else if (c == '/') {
2032 			len = 2;
2033 			str = "\\/";
2034 		}
2035 		else if (c == '\b') {
2036 			len = 2;
2037 			str = "\\b";
2038 		}
2039 		else if (c == '\f') {
2040 			len = 2;
2041 			str = "\\f";
2042 		}
2043 		else if (c == '\r') {
2044 			len = 2;
2045 			str = "\\r";
2046 		}
2047 		else if (c == '\n') {
2048 			len = 2;
2049 			str = "\\n";
2050 		}
2051 		else if (c == '\t') {
2052 			len = 2;
2053 			str = "\\t";
2054 		}
2055 		else if (c > 0xff || !isprint(c)) {
2056 			/* isprint generate a segfault if c is too big. The man says that
2057 			 * c must have the value of an unsigned char or EOF.
2058 			 */
2059 			len = 6;
2060 			_str[0] = '\\';
2061 			_str[1] = 'u';
2062 			snprintf(&_str[2], 5, "%04x", (unsigned short)c);
2063 			str = _str;
2064 		}
2065 		else {
2066 			len = 1;
2067 			_str[0] = c;
2068 			str = _str;
2069 		}
2070 
2071 		/* Check length */
2072 		if (temp->data + len > temp->size)
2073 			return 0;
2074 
2075 		/* Copy string. */
2076 		memcpy(temp->area + temp->data, str, len);
2077 		temp->data += len;
2078 	}
2079 
2080 	smp->flags &= ~SMP_F_CONST;
2081 	smp->data.u.str = *temp;
2082 	smp->data.type = SMP_T_STR;
2083 
2084 	return 1;
2085 }
2086 
2087 /* This sample function is designed to extract some bytes from an input buffer.
2088  * First arg is the offset.
2089  * Optional second arg is the length to truncate */
sample_conv_bytes(const struct arg * arg_p,struct sample * smp,void * private)2090 static int sample_conv_bytes(const struct arg *arg_p, struct sample *smp, void *private)
2091 {
2092 	if (smp->data.u.str.data <= arg_p[0].data.sint) {
2093 		smp->data.u.str.data = 0;
2094 		return 1;
2095 	}
2096 
2097 	if (smp->data.u.str.size)
2098 			smp->data.u.str.size -= arg_p[0].data.sint;
2099 	smp->data.u.str.data -= arg_p[0].data.sint;
2100 	smp->data.u.str.area += arg_p[0].data.sint;
2101 
2102 	if ((arg_p[1].type == ARGT_SINT) && (arg_p[1].data.sint < smp->data.u.str.data))
2103 		smp->data.u.str.data = arg_p[1].data.sint;
2104 
2105 	return 1;
2106 }
2107 
sample_conv_field_check(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)2108 static int sample_conv_field_check(struct arg *args, struct sample_conv *conv,
2109                                   const char *file, int line, char **err)
2110 {
2111 	struct arg *arg = args;
2112 
2113 	if (!arg) {
2114 		memprintf(err, "Unexpected empty arg list");
2115 		return 0;
2116 	}
2117 
2118 	if (arg->type != ARGT_SINT) {
2119 		memprintf(err, "Unexpected arg type");
2120 		return 0;
2121 	}
2122 
2123 	if (!arg->data.sint) {
2124 		memprintf(err, "Unexpected value 0 for index");
2125 		return 0;
2126 	}
2127 
2128 	arg++;
2129 
2130 	if (arg->type != ARGT_STR) {
2131 		memprintf(err, "Unexpected arg type");
2132 		return 0;
2133 	}
2134 
2135 	if (!arg->data.str.data) {
2136 		memprintf(err, "Empty separators list");
2137 		return 0;
2138 	}
2139 
2140 	return 1;
2141 }
2142 
2143 /* This sample function is designed to a return selected part of a string (field).
2144  * First arg is the index of the field (start at 1)
2145  * Second arg is a char list of separators (type string)
2146  */
sample_conv_field(const struct arg * arg_p,struct sample * smp,void * private)2147 static int sample_conv_field(const struct arg *arg_p, struct sample *smp, void *private)
2148 {
2149 	int field;
2150 	char *start, *end;
2151 	int i;
2152 	int count = (arg_p[2].type == ARGT_SINT) ? arg_p[2].data.sint : 1;
2153 
2154 	if (!arg_p[0].data.sint)
2155 		return 0;
2156 
2157 	if (arg_p[0].data.sint < 0) {
2158 		field = -1;
2159 		end = start = smp->data.u.str.area + smp->data.u.str.data;
2160 		while (start > smp->data.u.str.area) {
2161 			for (i = 0 ; i < arg_p[1].data.str.data; i++) {
2162 				if (*(start-1) == arg_p[1].data.str.area[i]) {
2163 					if (field == arg_p[0].data.sint) {
2164 						if (count == 1)
2165 							goto found;
2166 						else if (count > 1)
2167 							count--;
2168 					} else {
2169 						end = start-1;
2170 						field--;
2171 					}
2172 					break;
2173 				}
2174 			}
2175 			start--;
2176 		}
2177 	} else {
2178 		field = 1;
2179 		end = start = smp->data.u.str.area;
2180 		while (end - smp->data.u.str.area < smp->data.u.str.data) {
2181 			for (i = 0 ; i < arg_p[1].data.str.data; i++) {
2182 				if (*end == arg_p[1].data.str.area[i]) {
2183 					if (field == arg_p[0].data.sint) {
2184 						if (count == 1)
2185 							goto found;
2186 						else if (count > 1)
2187 							count--;
2188 					} else {
2189 						start = end+1;
2190 						field++;
2191 					}
2192 					break;
2193 				}
2194 			}
2195 			end++;
2196 		}
2197 	}
2198 
2199 	/* Field not found */
2200 	if (field != arg_p[0].data.sint) {
2201 		smp->data.u.str.data = 0;
2202 		return 0;
2203 	}
2204 found:
2205 	smp->data.u.str.data = end - start;
2206 	/* If ret string is len 0, no need to
2207            change pointers or to update size */
2208 	if (!smp->data.u.str.data)
2209 		return 1;
2210 
2211 	smp->data.u.str.area = start;
2212 
2213 	/* Compute remaining size if needed
2214            Note: smp->data.u.str.size cannot be set to 0 */
2215 	if (smp->data.u.str.size)
2216 		smp->data.u.str.size -= start - smp->data.u.str.area;
2217 
2218 	return 1;
2219 }
2220 
2221 /* This sample function is designed to return a word from a string.
2222  * First arg is the index of the word (start at 1)
2223  * Second arg is a char list of words separators (type string)
2224  */
sample_conv_word(const struct arg * arg_p,struct sample * smp,void * private)2225 static int sample_conv_word(const struct arg *arg_p, struct sample *smp, void *private)
2226 {
2227 	int word;
2228 	char *start, *end;
2229 	int i, issep, inword;
2230 	int count = (arg_p[2].type == ARGT_SINT) ? arg_p[2].data.sint : 1;
2231 
2232 	if (!arg_p[0].data.sint)
2233 		return 0;
2234 
2235 	word = 0;
2236 	inword = 0;
2237 	if (arg_p[0].data.sint < 0) {
2238 		end = start = smp->data.u.str.area + smp->data.u.str.data;
2239 		while (start > smp->data.u.str.area) {
2240 			issep = 0;
2241 			for (i = 0 ; i < arg_p[1].data.str.data; i++) {
2242 				if (*(start-1) == arg_p[1].data.str.area[i]) {
2243 					issep = 1;
2244 					break;
2245 				}
2246 			}
2247 			if (!inword) {
2248 				if (!issep) {
2249 					if (word != arg_p[0].data.sint) {
2250 						word--;
2251 						end = start;
2252 					}
2253 					inword = 1;
2254 				}
2255 			}
2256 			else if (issep) {
2257 				if (word == arg_p[0].data.sint) {
2258 					if (count == 1)
2259 						goto found;
2260 					else if (count > 1)
2261 						count--;
2262 				}
2263 				inword = 0;
2264 			}
2265 			start--;
2266 		}
2267 	} else {
2268 		end = start = smp->data.u.str.area;
2269 		while (end - smp->data.u.str.area < smp->data.u.str.data) {
2270 			issep = 0;
2271 			for (i = 0 ; i < arg_p[1].data.str.data; i++) {
2272 				if (*end == arg_p[1].data.str.area[i]) {
2273 					issep = 1;
2274 					break;
2275 				}
2276 			}
2277 			if (!inword) {
2278 				if (!issep) {
2279 					if (word != arg_p[0].data.sint) {
2280 						word++;
2281 						start = end;
2282 					}
2283 					inword = 1;
2284 				}
2285 			}
2286 			else if (issep) {
2287 				if (word == arg_p[0].data.sint) {
2288 					if (count == 1)
2289 						goto found;
2290 					else if (count > 1)
2291 						count--;
2292 				}
2293 				inword = 0;
2294 			}
2295 			end++;
2296 		}
2297 	}
2298 
2299 	/* Field not found */
2300 	if (word != arg_p[0].data.sint) {
2301 		smp->data.u.str.data = 0;
2302 		return 1;
2303 	}
2304 found:
2305 	smp->data.u.str.data = end - start;
2306 	/* If ret string is len 0, no need to
2307            change pointers or to update size */
2308 	if (!smp->data.u.str.data)
2309 		return 1;
2310 
2311 	smp->data.u.str.area = start;
2312 
2313 	/* Compute remaining size if needed
2314            Note: smp->data.u.str.size cannot be set to 0 */
2315 	if (smp->data.u.str.size)
2316 		smp->data.u.str.size -= start - smp->data.u.str.area;
2317 
2318 	return 1;
2319 }
2320 
sample_conv_regsub_check(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)2321 static int sample_conv_regsub_check(struct arg *args, struct sample_conv *conv,
2322                                     const char *file, int line, char **err)
2323 {
2324 	struct arg *arg = args;
2325 	char *p;
2326 	int len;
2327 
2328 	/* arg0 is a regex, it uses type_flag for ICASE and global match */
2329 	arg[0].type_flags = 0;
2330 
2331 	if (arg[2].type != ARGT_STR)
2332 		return 1;
2333 
2334 	p = arg[2].data.str.area;
2335 	len = arg[2].data.str.data;
2336 	while (len) {
2337 		if (*p == 'i') {
2338 			arg[0].type_flags |= ARGF_REG_ICASE;
2339 		}
2340 		else if (*p == 'g') {
2341 			arg[0].type_flags |= ARGF_REG_GLOB;
2342 		}
2343 		else {
2344 			memprintf(err, "invalid regex flag '%c', only 'i' and 'g' are supported", *p);
2345 			return 0;
2346 		}
2347 		p++;
2348 		len--;
2349 	}
2350 	return 1;
2351 }
2352 
2353 /* This sample function is designed to do the equivalent of s/match/replace/ on
2354  * the input string. It applies a regex and restarts from the last matched
2355  * location until nothing matches anymore. First arg is the regex to apply to
2356  * the input string, second arg is the replacement expression.
2357  */
sample_conv_regsub(const struct arg * arg_p,struct sample * smp,void * private)2358 static int sample_conv_regsub(const struct arg *arg_p, struct sample *smp, void *private)
2359 {
2360 	char *start, *end;
2361 	struct my_regex *reg = arg_p[0].data.reg;
2362 	regmatch_t pmatch[MAX_MATCH];
2363 	struct buffer *trash = get_trash_chunk();
2364 	int flag, max;
2365 	int found;
2366 
2367 	start = smp->data.u.str.area;
2368 	end = start + smp->data.u.str.data;
2369 
2370 	flag = 0;
2371 	while (1) {
2372 		/* check for last round which is used to copy remaining parts
2373 		 * when not running in global replacement mode.
2374 		 */
2375 		found = 0;
2376 		if ((arg_p[0].type_flags & ARGF_REG_GLOB) || !(flag & REG_NOTBOL)) {
2377 			/* Note: we can have start == end on empty strings or at the end */
2378 			found = regex_exec_match2(reg, start, end - start, MAX_MATCH, pmatch, flag);
2379 		}
2380 
2381 		if (!found)
2382 			pmatch[0].rm_so = end - start;
2383 
2384 		/* copy the heading non-matching part (which may also be the tail if nothing matches) */
2385 		max = trash->size - trash->data;
2386 		if (max && pmatch[0].rm_so > 0) {
2387 			if (max > pmatch[0].rm_so)
2388 				max = pmatch[0].rm_so;
2389 			memcpy(trash->area + trash->data, start, max);
2390 			trash->data += max;
2391 		}
2392 
2393 		if (!found)
2394 			break;
2395 
2396 		/* replace the matching part */
2397 		max = trash->size - trash->data;
2398 		if (max) {
2399 			if (max > arg_p[1].data.str.data)
2400 				max = arg_p[1].data.str.data;
2401 			memcpy(trash->area + trash->data,
2402 			       arg_p[1].data.str.area, max);
2403 			trash->data += max;
2404 		}
2405 
2406 		/* stop here if we're done with this string */
2407 		if (start >= end)
2408 			break;
2409 
2410 		/* We have a special case for matches of length 0 (eg: "x*y*").
2411 		 * These ones are considered to match in front of a character,
2412 		 * so we have to copy that character and skip to the next one.
2413 		 */
2414 		if (!pmatch[0].rm_eo) {
2415 			if (trash->data < trash->size)
2416 				trash->area[trash->data++] = start[pmatch[0].rm_eo];
2417 			pmatch[0].rm_eo++;
2418 		}
2419 
2420 		start += pmatch[0].rm_eo;
2421 		flag |= REG_NOTBOL;
2422 	}
2423 
2424 	smp->data.u.str = *trash;
2425 	return 1;
2426 }
2427 
2428 /* This function check an operator entry. It expects a string.
2429  * The string can be an integer or a variable name.
2430  */
check_operator(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)2431 static int check_operator(struct arg *args, struct sample_conv *conv,
2432                           const char *file, int line, char **err)
2433 {
2434 	const char *str;
2435 	const char *end;
2436 
2437 	/* Try to decode a variable. */
2438 	if (vars_check_arg(&args[0], NULL))
2439 		return 1;
2440 
2441 	/* Try to convert an integer */
2442 	str = args[0].data.str.area;
2443 	end = str + strlen(str);
2444 	args[0].data.sint = read_int64(&str, end);
2445 	if (*str != '\0') {
2446 		memprintf(err, "expects an integer or a variable name");
2447 		return 0;
2448 	}
2449 	args[0].type = ARGT_SINT;
2450 	return 1;
2451 }
2452 
2453 /* This function returns a sample struct filled with an arg content.
2454  * If the arg contain an integer, the integer is returned in the
2455  * sample. If the arg contains a variable descriptor, it returns the
2456  * variable value.
2457  *
2458  * This function returns 0 if an error occurs, otherwise it returns 1.
2459  */
sample_conv_var2smp(const struct arg * arg,struct sample * smp)2460 static inline int sample_conv_var2smp(const struct arg *arg, struct sample *smp)
2461 {
2462 	switch (arg->type) {
2463 	case ARGT_SINT:
2464 		smp->data.type = SMP_T_SINT;
2465 		smp->data.u.sint = arg->data.sint;
2466 		return 1;
2467 	case ARGT_VAR:
2468 		if (!vars_get_by_desc(&arg->data.var, smp))
2469 			return 0;
2470 		if (!sample_casts[smp->data.type][SMP_T_SINT])
2471 			return 0;
2472 		if (!sample_casts[smp->data.type][SMP_T_SINT](smp))
2473 			return 0;
2474 		return 1;
2475 	default:
2476 		return 0;
2477 	}
2478 }
2479 
2480 /* Takes a SINT on input, applies a binary twos complement and returns the SINT
2481  * result.
2482  */
sample_conv_binary_cpl(const struct arg * arg_p,struct sample * smp,void * private)2483 static int sample_conv_binary_cpl(const struct arg *arg_p, struct sample *smp, void *private)
2484 {
2485 	smp->data.u.sint = ~smp->data.u.sint;
2486 	return 1;
2487 }
2488 
2489 /* Takes a SINT on input, applies a binary "and" with the SINT directly in
2490  * arg_p or in the variable described in arg_p, and returns the SINT result.
2491  */
sample_conv_binary_and(const struct arg * arg_p,struct sample * smp,void * private)2492 static int sample_conv_binary_and(const struct arg *arg_p, struct sample *smp, void *private)
2493 {
2494 	struct sample tmp;
2495 
2496 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2497 	if (!sample_conv_var2smp(arg_p, &tmp))
2498 		return 0;
2499 	smp->data.u.sint &= tmp.data.u.sint;
2500 	return 1;
2501 }
2502 
2503 /* Takes a SINT on input, applies a binary "or" with the SINT directly in
2504  * arg_p or in the variable described in arg_p, and returns the SINT result.
2505  */
sample_conv_binary_or(const struct arg * arg_p,struct sample * smp,void * private)2506 static int sample_conv_binary_or(const struct arg *arg_p, struct sample *smp, void *private)
2507 {
2508 	struct sample tmp;
2509 
2510 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2511 	if (!sample_conv_var2smp(arg_p, &tmp))
2512 		return 0;
2513 	smp->data.u.sint |= tmp.data.u.sint;
2514 	return 1;
2515 }
2516 
2517 /* Takes a SINT on input, applies a binary "xor" with the SINT directly in
2518  * arg_p or in the variable described in arg_p, and returns the SINT result.
2519  */
sample_conv_binary_xor(const struct arg * arg_p,struct sample * smp,void * private)2520 static int sample_conv_binary_xor(const struct arg *arg_p, struct sample *smp, void *private)
2521 {
2522 	struct sample tmp;
2523 
2524 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2525 	if (!sample_conv_var2smp(arg_p, &tmp))
2526 		return 0;
2527 	smp->data.u.sint ^= tmp.data.u.sint;
2528 	return 1;
2529 }
2530 
arith_add(long long int a,long long int b)2531 static inline long long int arith_add(long long int a, long long int b)
2532 {
2533 	/* Prevent overflow and makes capped calculus.
2534 	 * We must ensure that the check calculus doesn't
2535 	 * exceed the signed 64 bits limits.
2536 	 *
2537 	 *        +----------+----------+
2538 	 *        |   a<0    |   a>=0   |
2539 	 * +------+----------+----------+
2540 	 * | b<0  | MIN-a>b  | no check |
2541 	 * +------+----------+----------+
2542 	 * | b>=0 | no check | MAX-a<b  |
2543 	 * +------+----------+----------+
2544 	 */
2545 	if ((a ^ b) >= 0) {
2546 		/* signs are differents. */
2547 		if (a < 0) {
2548 			if (LLONG_MIN - a > b)
2549 				return LLONG_MIN;
2550 		}
2551 		if (LLONG_MAX - a < b)
2552 			return LLONG_MAX;
2553 	}
2554 	return a + b;
2555 }
2556 
2557 /* Takes a SINT on input, applies an arithmetic "add" with the SINT directly in
2558  * arg_p or in the variable described in arg_p, and returns the SINT result.
2559  */
sample_conv_arith_add(const struct arg * arg_p,struct sample * smp,void * private)2560 static int sample_conv_arith_add(const struct arg *arg_p, struct sample *smp, void *private)
2561 {
2562 	struct sample tmp;
2563 
2564 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2565 	if (!sample_conv_var2smp(arg_p, &tmp))
2566 		return 0;
2567 	smp->data.u.sint = arith_add(smp->data.u.sint, tmp.data.u.sint);
2568 	return 1;
2569 }
2570 
2571 /* Takes a SINT on input, applies an arithmetic "sub" with the SINT directly in
2572  * arg_p or in the variable described in arg_p, and returns the SINT result.
2573  */
sample_conv_arith_sub(const struct arg * arg_p,struct sample * smp,void * private)2574 static int sample_conv_arith_sub(const struct arg *arg_p,
2575                                  struct sample *smp, void *private)
2576 {
2577 	struct sample tmp;
2578 
2579 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2580 	if (!sample_conv_var2smp(arg_p, &tmp))
2581 		return 0;
2582 
2583 	/* We cannot represent -LLONG_MIN because abs(LLONG_MIN) is greater
2584 	 * than abs(LLONG_MAX). So, the following code use LLONG_MAX in place
2585 	 * of -LLONG_MIN and correct the result.
2586 	 */
2587 	if (tmp.data.u.sint == LLONG_MIN) {
2588 		smp->data.u.sint = arith_add(smp->data.u.sint, LLONG_MAX);
2589 		if (smp->data.u.sint < LLONG_MAX)
2590 			smp->data.u.sint++;
2591 		return 1;
2592 	}
2593 
2594 	/* standard subtraction: we use the "add" function and negate
2595 	 * the second operand.
2596 	 */
2597 	smp->data.u.sint = arith_add(smp->data.u.sint, -tmp.data.u.sint);
2598 	return 1;
2599 }
2600 
2601 /* Takes a SINT on input, applies an arithmetic "mul" with the SINT directly in
2602  * arg_p or in the variable described in arg_p, and returns the SINT result.
2603  * If the result makes an overflow, then the largest possible quantity is
2604  * returned.
2605  */
sample_conv_arith_mul(const struct arg * arg_p,struct sample * smp,void * private)2606 static int sample_conv_arith_mul(const struct arg *arg_p,
2607                                  struct sample *smp, void *private)
2608 {
2609 	struct sample tmp;
2610 	long long int c;
2611 
2612 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2613 	if (!sample_conv_var2smp(arg_p, &tmp))
2614 		return 0;
2615 
2616 	/* prevent divide by 0 during the check */
2617 	if (!smp->data.u.sint || !tmp.data.u.sint) {
2618 		smp->data.u.sint = 0;
2619 		return 1;
2620 	}
2621 
2622 	/* The multiply between LLONG_MIN and -1 returns a
2623 	 * "floting point exception".
2624 	 */
2625 	if (smp->data.u.sint == LLONG_MIN && tmp.data.u.sint == -1) {
2626 		smp->data.u.sint = LLONG_MAX;
2627 		return 1;
2628 	}
2629 
2630 	/* execute standard multiplication. */
2631 	c = smp->data.u.sint * tmp.data.u.sint;
2632 
2633 	/* check for overflow and makes capped multiply. */
2634 	if (smp->data.u.sint != c / tmp.data.u.sint) {
2635 		if ((smp->data.u.sint < 0) == (tmp.data.u.sint < 0)) {
2636 			smp->data.u.sint = LLONG_MAX;
2637 			return 1;
2638 		}
2639 		smp->data.u.sint = LLONG_MIN;
2640 		return 1;
2641 	}
2642 	smp->data.u.sint = c;
2643 	return 1;
2644 }
2645 
2646 /* Takes a SINT on input, applies an arithmetic "div" with the SINT directly in
2647  * arg_p or in the variable described in arg_p, and returns the SINT result.
2648  * If arg_p makes the result overflow, then the largest possible quantity is
2649  * returned.
2650  */
sample_conv_arith_div(const struct arg * arg_p,struct sample * smp,void * private)2651 static int sample_conv_arith_div(const struct arg *arg_p,
2652                                  struct sample *smp, void *private)
2653 {
2654 	struct sample tmp;
2655 
2656 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2657 	if (!sample_conv_var2smp(arg_p, &tmp))
2658 		return 0;
2659 
2660 	if (tmp.data.u.sint) {
2661 		/* The divide between LLONG_MIN and -1 returns a
2662 		 * "floting point exception".
2663 		 */
2664 		if (smp->data.u.sint == LLONG_MIN && tmp.data.u.sint == -1) {
2665 			smp->data.u.sint = LLONG_MAX;
2666 			return 1;
2667 		}
2668 		smp->data.u.sint /= tmp.data.u.sint;
2669 		return 1;
2670 	}
2671 	smp->data.u.sint = LLONG_MAX;
2672 	return 1;
2673 }
2674 
2675 /* Takes a SINT on input, applies an arithmetic "mod" with the SINT directly in
2676  * arg_p or in the variable described in arg_p, and returns the SINT result.
2677  * If arg_p makes the result overflow, then 0 is returned.
2678  */
sample_conv_arith_mod(const struct arg * arg_p,struct sample * smp,void * private)2679 static int sample_conv_arith_mod(const struct arg *arg_p,
2680                                  struct sample *smp, void *private)
2681 {
2682 	struct sample tmp;
2683 
2684 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2685 	if (!sample_conv_var2smp(arg_p, &tmp))
2686 		return 0;
2687 
2688 	if (tmp.data.u.sint) {
2689 		/* The divide between LLONG_MIN and -1 returns a
2690 		 * "floting point exception".
2691 		 */
2692 		if (smp->data.u.sint == LLONG_MIN && tmp.data.u.sint == -1) {
2693 			smp->data.u.sint = 0;
2694 			return 1;
2695 		}
2696 		smp->data.u.sint %= tmp.data.u.sint;
2697 		return 1;
2698 	}
2699 	smp->data.u.sint = 0;
2700 	return 1;
2701 }
2702 
2703 /* Takes an SINT on input, applies an arithmetic "neg" and returns the SINT
2704  * result.
2705  */
sample_conv_arith_neg(const struct arg * arg_p,struct sample * smp,void * private)2706 static int sample_conv_arith_neg(const struct arg *arg_p,
2707                                  struct sample *smp, void *private)
2708 {
2709 	if (smp->data.u.sint == LLONG_MIN)
2710 		smp->data.u.sint = LLONG_MAX;
2711 	else
2712 		smp->data.u.sint = -smp->data.u.sint;
2713 	return 1;
2714 }
2715 
2716 /* Takes a SINT on input, returns true is the value is non-null, otherwise
2717  * false. The output is a BOOL.
2718  */
sample_conv_arith_bool(const struct arg * arg_p,struct sample * smp,void * private)2719 static int sample_conv_arith_bool(const struct arg *arg_p,
2720                                   struct sample *smp, void *private)
2721 {
2722 	smp->data.u.sint = !!smp->data.u.sint;
2723 	smp->data.type = SMP_T_BOOL;
2724 	return 1;
2725 }
2726 
2727 /* Takes a SINT on input, returns false is the value is non-null, otherwise
2728  * truee. The output is a BOOL.
2729  */
sample_conv_arith_not(const struct arg * arg_p,struct sample * smp,void * private)2730 static int sample_conv_arith_not(const struct arg *arg_p,
2731                                  struct sample *smp, void *private)
2732 {
2733 	smp->data.u.sint = !smp->data.u.sint;
2734 	smp->data.type = SMP_T_BOOL;
2735 	return 1;
2736 }
2737 
2738 /* Takes a SINT on input, returns true is the value is odd, otherwise false.
2739  * The output is a BOOL.
2740  */
sample_conv_arith_odd(const struct arg * arg_p,struct sample * smp,void * private)2741 static int sample_conv_arith_odd(const struct arg *arg_p,
2742                                  struct sample *smp, void *private)
2743 {
2744 	smp->data.u.sint = smp->data.u.sint & 1;
2745 	smp->data.type = SMP_T_BOOL;
2746 	return 1;
2747 }
2748 
2749 /* Takes a SINT on input, returns true is the value is even, otherwise false.
2750  * The output is a BOOL.
2751  */
sample_conv_arith_even(const struct arg * arg_p,struct sample * smp,void * private)2752 static int sample_conv_arith_even(const struct arg *arg_p,
2753                                   struct sample *smp, void *private)
2754 {
2755 	smp->data.u.sint = !(smp->data.u.sint & 1);
2756 	smp->data.type = SMP_T_BOOL;
2757 	return 1;
2758 }
2759 
2760 /* appends an optional const string, an optional variable contents and another
2761  * optional const string to an existing string.
2762  */
sample_conv_concat(const struct arg * arg_p,struct sample * smp,void * private)2763 static int sample_conv_concat(const struct arg *arg_p, struct sample *smp, void *private)
2764 {
2765 	struct buffer *trash;
2766 	struct sample tmp;
2767 	int max;
2768 
2769 	trash = get_trash_chunk();
2770 	trash->data = smp->data.u.str.data;
2771 	if (trash->data > trash->size - 1)
2772 		trash->data = trash->size - 1;
2773 
2774 	memcpy(trash->area, smp->data.u.str.area, trash->data);
2775 	trash->area[trash->data] = 0;
2776 
2777 	/* append first string */
2778 	max = arg_p[0].data.str.data;
2779 	if (max > trash->size - 1 - trash->data)
2780 		max = trash->size - 1 - trash->data;
2781 
2782 	if (max) {
2783 		memcpy(trash->area + trash->data, arg_p[0].data.str.area, max);
2784 		trash->data += max;
2785 		trash->area[trash->data] = 0;
2786 	}
2787 
2788 	/* append second string (variable) if it's found and we can turn it
2789 	 * into a string.
2790 	 */
2791 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2792 	if (arg_p[1].type == ARGT_VAR && vars_get_by_desc(&arg_p[1].data.var, &tmp) &&
2793 	    (sample_casts[tmp.data.type][SMP_T_STR] == c_none ||
2794 	     sample_casts[tmp.data.type][SMP_T_STR](&tmp))) {
2795 
2796 		max = tmp.data.u.str.data;
2797 		if (max > trash->size - 1 - trash->data)
2798 			max = trash->size - 1 - trash->data;
2799 
2800 		if (max) {
2801 			memcpy(trash->area + trash->data, tmp.data.u.str.area,
2802 			       max);
2803 			trash->data += max;
2804 			trash->area[trash->data] = 0;
2805 		}
2806 	}
2807 
2808 	/* append third string */
2809 	max = arg_p[2].data.str.data;
2810 	if (max > trash->size - 1 - trash->data)
2811 		max = trash->size - 1 - trash->data;
2812 
2813 	if (max) {
2814 		memcpy(trash->area + trash->data, arg_p[2].data.str.area, max);
2815 		trash->data += max;
2816 		trash->area[trash->data] = 0;
2817 	}
2818 
2819 	smp->data.u.str = *trash;
2820 	smp->data.type = SMP_T_STR;
2821 	return 1;
2822 }
2823 
2824 /* This function checks the "concat" converter's arguments and extracts the
2825  * variable name and its scope.
2826  */
smp_check_concat(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)2827 static int smp_check_concat(struct arg *args, struct sample_conv *conv,
2828                            const char *file, int line, char **err)
2829 {
2830 	/* Try to decode a variable. */
2831 	if (args[1].data.str.data > 0 && !vars_check_arg(&args[1], NULL)) {
2832 		memprintf(err, "failed to register variable name '%s'",
2833 			  args[1].data.str.area);
2834 		return 0;
2835 	}
2836 	return 1;
2837 }
2838 
2839 /* compares string with a variable containing a string. Return value
2840  * is compatible with strcmp(3)'s return value.
2841  */
sample_conv_strcmp(const struct arg * arg_p,struct sample * smp,void * private)2842 static int sample_conv_strcmp(const struct arg *arg_p, struct sample *smp, void *private)
2843 {
2844 	struct sample tmp;
2845 	int max, result;
2846 
2847 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2848 	if (arg_p[0].type != ARGT_VAR)
2849 		return 0;
2850 	if (!vars_get_by_desc(&arg_p[0].data.var, &tmp))
2851 		return 0;
2852 	if (!sample_casts[tmp.data.type][SMP_T_STR](&tmp))
2853 		return 0;
2854 
2855 	max = MIN(smp->data.u.str.data, tmp.data.u.str.data);
2856 	result = strncmp(smp->data.u.str.area, tmp.data.u.str.area, max);
2857 	if (result == 0) {
2858 		if (smp->data.u.str.data != tmp.data.u.str.data) {
2859 			if (smp->data.u.str.data < tmp.data.u.str.data) {
2860 				result = -1;
2861 			}
2862 			else {
2863 				result = 1;
2864 			}
2865 		}
2866 	}
2867 
2868 	smp->data.u.sint = result;
2869 	smp->data.type = SMP_T_SINT;
2870 	return 1;
2871 }
2872 
2873 #define GRPC_MSG_COMPRESS_FLAG_SZ 1 /* 1 byte */
2874 #define GRPC_MSG_LENGTH_SZ        4 /* 4 bytes */
2875 #define GRPC_MSG_HEADER_SZ        (GRPC_MSG_COMPRESS_FLAG_SZ + GRPC_MSG_LENGTH_SZ)
2876 
2877 /*
2878  * Extract the field value of an input binary sample. Takes a mandatory argument:
2879  * the protocol buffers field identifier (dotted notation) internally represented
2880  * as an array of unsigned integers and its size.
2881  * Return 1 if the field was found, 0 if not.
2882  */
sample_conv_ungrpc(const struct arg * arg_p,struct sample * smp,void * private)2883 static int sample_conv_ungrpc(const struct arg *arg_p, struct sample *smp, void *private)
2884 {
2885 	unsigned char *pos;
2886 	size_t grpc_left;
2887 
2888 	pos = (unsigned char *)smp->data.u.str.area;
2889 	grpc_left = smp->data.u.str.data;
2890 
2891 	while (grpc_left > GRPC_MSG_HEADER_SZ) {
2892 		size_t grpc_msg_len, left;
2893 
2894 		grpc_msg_len = left = ntohl(*(uint32_t *)(pos + GRPC_MSG_COMPRESS_FLAG_SZ));
2895 
2896 		pos += GRPC_MSG_HEADER_SZ;
2897 		grpc_left -= GRPC_MSG_HEADER_SZ;
2898 
2899 		if (grpc_left < left)
2900 			return 0;
2901 
2902 		if (protobuf_field_lookup(arg_p, smp, &pos, &left))
2903 			return 1;
2904 
2905 		grpc_left -= grpc_msg_len;
2906 	}
2907 
2908 	return 0;
2909 }
2910 
sample_conv_protobuf(const struct arg * arg_p,struct sample * smp,void * private)2911 static int sample_conv_protobuf(const struct arg *arg_p, struct sample *smp, void *private)
2912 {
2913 	unsigned char *pos;
2914 	size_t left;
2915 
2916 	pos = (unsigned char *)smp->data.u.str.area;
2917 	left = smp->data.u.str.data;
2918 
2919 	return protobuf_field_lookup(arg_p, smp, &pos, &left);
2920 }
2921 
sample_conv_protobuf_check(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)2922 static int sample_conv_protobuf_check(struct arg *args, struct sample_conv *conv,
2923                                       const char *file, int line, char **err)
2924 {
2925 	if (!args[1].type) {
2926 		args[1].type = ARGT_SINT;
2927 		args[1].data.sint = PBUF_T_BINARY;
2928 	}
2929 	else {
2930 		int pbuf_type;
2931 
2932 		pbuf_type = protobuf_type(args[1].data.str.area);
2933 		if (pbuf_type == -1) {
2934 			memprintf(err, "Wrong protocol buffer type '%s'", args[1].data.str.area);
2935 			return 0;
2936 		}
2937 
2938 		args[1].type = ARGT_SINT;
2939 		args[1].data.sint = pbuf_type;
2940 	}
2941 
2942 	return 1;
2943 }
2944 
2945 /* This function checks the "strcmp" converter's arguments and extracts the
2946  * variable name and its scope.
2947  */
smp_check_strcmp(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)2948 static int smp_check_strcmp(struct arg *args, struct sample_conv *conv,
2949                            const char *file, int line, char **err)
2950 {
2951 	/* Try to decode a variable. */
2952 	if (vars_check_arg(&args[0], NULL))
2953 		return 1;
2954 
2955 	memprintf(err, "failed to register variable name '%s'",
2956 		  args[0].data.str.area);
2957 	return 0;
2958 }
2959 
2960 /************************************************************************/
2961 /*       All supported sample fetch functions must be declared here     */
2962 /************************************************************************/
2963 
2964 /* force TRUE to be returned at the fetch level */
2965 static int
smp_fetch_true(const struct arg * args,struct sample * smp,const char * kw,void * private)2966 smp_fetch_true(const struct arg *args, struct sample *smp, const char *kw, void *private)
2967 {
2968 	if (!smp_make_rw(smp))
2969 		return 0;
2970 
2971 	smp->data.type = SMP_T_BOOL;
2972 	smp->data.u.sint = 1;
2973 	return 1;
2974 }
2975 
2976 /* force FALSE to be returned at the fetch level */
2977 static int
smp_fetch_false(const struct arg * args,struct sample * smp,const char * kw,void * private)2978 smp_fetch_false(const struct arg *args, struct sample *smp, const char *kw, void *private)
2979 {
2980 	smp->data.type = SMP_T_BOOL;
2981 	smp->data.u.sint = 0;
2982 	return 1;
2983 }
2984 
2985 /* retrieve environment variable $1 as a string */
2986 static int
smp_fetch_env(const struct arg * args,struct sample * smp,const char * kw,void * private)2987 smp_fetch_env(const struct arg *args, struct sample *smp, const char *kw, void *private)
2988 {
2989 	char *env;
2990 
2991 	if (!args || args[0].type != ARGT_STR)
2992 		return 0;
2993 
2994 	env = getenv(args[0].data.str.area);
2995 	if (!env)
2996 		return 0;
2997 
2998 	smp->data.type = SMP_T_STR;
2999 	smp->flags = SMP_F_CONST;
3000 	smp->data.u.str.area = env;
3001 	smp->data.u.str.data = strlen(env);
3002 	return 1;
3003 }
3004 
3005 /* Validates the data unit argument passed to "date" fetch. Argument 1 support an
3006  * optional string representing the unit of the result: "s" for seconds, "ms" for
3007  * milliseconds and "us" for microseconds.
3008  * Returns 0 on error and non-zero if OK.
3009  */
smp_check_date_unit(struct arg * args,char ** err)3010 int smp_check_date_unit(struct arg *args, char **err)
3011 {
3012         if (args[1].type == ARGT_STR) {
3013                 if (strcmp(args[1].data.str.area, "s") == 0) {
3014                         args[1].data.sint = TIME_UNIT_S;
3015                 }
3016                 else if (strcmp(args[1].data.str.area, "ms") == 0) {
3017                         args[1].data.sint = TIME_UNIT_MS;
3018                 }
3019                 else if (strcmp(args[1].data.str.area, "us") == 0) {
3020                         args[1].data.sint = TIME_UNIT_US;
3021                 }
3022                 else {
3023                         memprintf(err, "expects 's', 'ms' or 'us', got '%s'",
3024                                   args[1].data.str.area);
3025                         return 0;
3026                 }
3027                 free(args[1].data.str.area);
3028                 args[1].data.str.area = NULL;
3029                 args[1].type = ARGT_SINT;
3030         }
3031         else if (args[1].type != ARGT_STOP) {
3032                 memprintf(err, "Unexpected arg type");
3033                 return 0;
3034         }
3035 
3036         return 1;
3037 }
3038 
3039 /* retrieve the current local date in epoch time, converts it to milliseconds
3040  * or microseconds if asked to in optional args[1] unit param, and applies an
3041  * optional args[0] offset.
3042  */
3043 static int
smp_fetch_date(const struct arg * args,struct sample * smp,const char * kw,void * private)3044 smp_fetch_date(const struct arg *args, struct sample *smp, const char *kw, void *private)
3045 {
3046 	smp->data.u.sint = date.tv_sec;
3047 
3048 	/* report in milliseconds */
3049 	if (args && args[1].type == ARGT_SINT && args[1].data.sint == TIME_UNIT_MS) {
3050 		smp->data.u.sint *= 1000;
3051 		smp->data.u.sint += date.tv_usec / 1000;
3052 	}
3053 	/* report in microseconds */
3054 	else if (args && args[1].type == ARGT_SINT && args[1].data.sint == TIME_UNIT_US) {
3055 		smp->data.u.sint *= 1000000;
3056 		smp->data.u.sint += date.tv_usec;
3057 	}
3058 
3059 	/* add offset */
3060 	if (args && args[0].type == ARGT_SINT)
3061 		smp->data.u.sint += args[0].data.sint;
3062 
3063 	smp->data.type = SMP_T_SINT;
3064 	smp->flags |= SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
3065 	return 1;
3066 }
3067 
3068 /* retrieve the current microsecond part of the date  */
3069 static int
smp_fetch_date_us(const struct arg * args,struct sample * smp,const char * kw,void * private)3070 smp_fetch_date_us(const struct arg *args, struct sample *smp, const char *kw, void *private)
3071 {
3072 	smp->data.u.sint = date.tv_usec;
3073 	smp->data.type = SMP_T_SINT;
3074 	smp->flags |= SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
3075 	return 1;
3076 }
3077 
3078 
3079 /* returns the hostname */
3080 static int
smp_fetch_hostname(const struct arg * args,struct sample * smp,const char * kw,void * private)3081 smp_fetch_hostname(const struct arg *args, struct sample *smp, const char *kw, void *private)
3082 {
3083 	smp->data.type = SMP_T_STR;
3084 	smp->flags = SMP_F_CONST;
3085 	smp->data.u.str.area = hostname;
3086 	smp->data.u.str.data = strlen(hostname);
3087 	return 1;
3088 }
3089 
3090 /* returns the number of processes */
3091 static int
smp_fetch_nbproc(const struct arg * args,struct sample * smp,const char * kw,void * private)3092 smp_fetch_nbproc(const struct arg *args, struct sample *smp, const char *kw, void *private)
3093 {
3094 	smp->data.type = SMP_T_SINT;
3095 	smp->data.u.sint = global.nbproc;
3096 	return 1;
3097 }
3098 
3099 /* returns the number of the current process (between 1 and nbproc */
3100 static int
smp_fetch_proc(const struct arg * args,struct sample * smp,const char * kw,void * private)3101 smp_fetch_proc(const struct arg *args, struct sample *smp, const char *kw, void *private)
3102 {
3103 	smp->data.type = SMP_T_SINT;
3104 	smp->data.u.sint = relative_pid;
3105 	return 1;
3106 }
3107 
3108 /* returns the number of the current thread (between 1 and nbthread */
3109 static int
smp_fetch_thread(const struct arg * args,struct sample * smp,const char * kw,void * private)3110 smp_fetch_thread(const struct arg *args, struct sample *smp, const char *kw, void *private)
3111 {
3112 	smp->data.type = SMP_T_SINT;
3113 	smp->data.u.sint = tid;
3114 	return 1;
3115 }
3116 
3117 /* generate a random 32-bit integer for whatever purpose, with an optional
3118  * range specified in argument.
3119  */
3120 static int
smp_fetch_rand(const struct arg * args,struct sample * smp,const char * kw,void * private)3121 smp_fetch_rand(const struct arg *args, struct sample *smp, const char *kw, void *private)
3122 {
3123 	smp->data.u.sint = ha_random();
3124 
3125 	/* reduce if needed. Don't do a modulo, use all bits! */
3126 	if (args && args[0].type == ARGT_SINT)
3127 		smp->data.u.sint = (smp->data.u.sint * args[0].data.sint) / ((u64)RAND_MAX+1);
3128 
3129 	smp->data.type = SMP_T_SINT;
3130 	smp->flags |= SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
3131 	return 1;
3132 }
3133 
3134 /* returns true if the current process is stopping */
3135 static int
smp_fetch_stopping(const struct arg * args,struct sample * smp,const char * kw,void * private)3136 smp_fetch_stopping(const struct arg *args, struct sample *smp, const char *kw, void *private)
3137 {
3138 	smp->data.type = SMP_T_BOOL;
3139 	smp->data.u.sint = stopping;
3140 	return 1;
3141 }
3142 
3143 /* returns the number of calls of the current stream's process_stream() */
3144 static int
smp_fetch_cpu_calls(const struct arg * args,struct sample * smp,const char * kw,void * private)3145 smp_fetch_cpu_calls(const struct arg *args, struct sample *smp, const char *kw, void *private)
3146 {
3147 	smp->data.type = SMP_T_SINT;
3148 	smp->data.u.sint = smp->strm->task->calls;
3149 	return 1;
3150 }
3151 
3152 /* returns the average number of nanoseconds spent processing the stream per call */
3153 static int
smp_fetch_cpu_ns_avg(const struct arg * args,struct sample * smp,const char * kw,void * private)3154 smp_fetch_cpu_ns_avg(const struct arg *args, struct sample *smp, const char *kw, void *private)
3155 {
3156 	smp->data.type = SMP_T_SINT;
3157 	smp->data.u.sint = smp->strm->task->calls ? smp->strm->task->cpu_time / smp->strm->task->calls : 0;
3158 	return 1;
3159 }
3160 
3161 /* returns the total number of nanoseconds spent processing the stream */
3162 static int
smp_fetch_cpu_ns_tot(const struct arg * args,struct sample * smp,const char * kw,void * private)3163 smp_fetch_cpu_ns_tot(const struct arg *args, struct sample *smp, const char *kw, void *private)
3164 {
3165 	smp->data.type = SMP_T_SINT;
3166 	smp->data.u.sint = smp->strm->task->cpu_time;
3167 	return 1;
3168 }
3169 
3170 /* returns the average number of nanoseconds per call spent waiting for other tasks to be processed */
3171 static int
smp_fetch_lat_ns_avg(const struct arg * args,struct sample * smp,const char * kw,void * private)3172 smp_fetch_lat_ns_avg(const struct arg *args, struct sample *smp, const char *kw, void *private)
3173 {
3174 	smp->data.type = SMP_T_SINT;
3175 	smp->data.u.sint = smp->strm->task->calls ? smp->strm->task->lat_time / smp->strm->task->calls : 0;
3176 	return 1;
3177 }
3178 
3179 /* returns the total number of nanoseconds per call spent waiting for other tasks to be processed */
3180 static int
smp_fetch_lat_ns_tot(const struct arg * args,struct sample * smp,const char * kw,void * private)3181 smp_fetch_lat_ns_tot(const struct arg *args, struct sample *smp, const char *kw, void *private)
3182 {
3183 	smp->data.type = SMP_T_SINT;
3184 	smp->data.u.sint = smp->strm->task->lat_time;
3185 	return 1;
3186 }
3187 
smp_fetch_const_str(const struct arg * args,struct sample * smp,const char * kw,void * private)3188 static int smp_fetch_const_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
3189 {
3190 	smp->flags |= SMP_F_CONST;
3191 	smp->data.type = SMP_T_STR;
3192 	smp->data.u.str.area = args[0].data.str.area;
3193 	smp->data.u.str.data = args[0].data.str.data;
3194 	return 1;
3195 }
3196 
smp_check_const_bool(struct arg * args,char ** err)3197 static int smp_check_const_bool(struct arg *args, char **err)
3198 {
3199 	if (strcasecmp(args[0].data.str.area, "true") == 0 ||
3200 	    strcasecmp(args[0].data.str.area, "1") == 0) {
3201 		args[0].type = ARGT_SINT;
3202 		args[0].data.sint = 1;
3203 		return 1;
3204 	}
3205 	if (strcasecmp(args[0].data.str.area, "false") == 0 ||
3206 	    strcasecmp(args[0].data.str.area, "0") == 0) {
3207 		args[0].type = ARGT_SINT;
3208 		args[0].data.sint = 0;
3209 		return 1;
3210 	}
3211 	memprintf(err, "Expects 'true', 'false', '0' or '1'");
3212 	return 0;
3213 }
3214 
smp_fetch_const_bool(const struct arg * args,struct sample * smp,const char * kw,void * private)3215 static int smp_fetch_const_bool(const struct arg *args, struct sample *smp, const char *kw, void *private)
3216 {
3217 	smp->data.type = SMP_T_BOOL;
3218 	smp->data.u.sint = args[0].data.sint;
3219 	return 1;
3220 }
3221 
smp_fetch_const_int(const struct arg * args,struct sample * smp,const char * kw,void * private)3222 static int smp_fetch_const_int(const struct arg *args, struct sample *smp, const char *kw, void *private)
3223 {
3224 	smp->data.type = SMP_T_SINT;
3225 	smp->data.u.sint = args[0].data.sint;
3226 	return 1;
3227 }
3228 
smp_fetch_const_ipv4(const struct arg * args,struct sample * smp,const char * kw,void * private)3229 static int smp_fetch_const_ipv4(const struct arg *args, struct sample *smp, const char *kw, void *private)
3230 {
3231 	smp->data.type = SMP_T_IPV4;
3232 	smp->data.u.ipv4 = args[0].data.ipv4;
3233 	return 1;
3234 }
3235 
smp_fetch_const_ipv6(const struct arg * args,struct sample * smp,const char * kw,void * private)3236 static int smp_fetch_const_ipv6(const struct arg *args, struct sample *smp, const char *kw, void *private)
3237 {
3238 	smp->data.type = SMP_T_IPV6;
3239 	smp->data.u.ipv6 = args[0].data.ipv6;
3240 	return 1;
3241 }
3242 
smp_check_const_bin(struct arg * args,char ** err)3243 static int smp_check_const_bin(struct arg *args, char **err)
3244 {
3245 	char *binstr = NULL;
3246 	int binstrlen;
3247 
3248 	if (!parse_binary(args[0].data.str.area, &binstr, &binstrlen, err))
3249 		return 0;
3250 	args[0].type = ARGT_STR;
3251 	args[0].data.str.area = binstr;
3252 	args[0].data.str.data = binstrlen;
3253 	return 1;
3254 }
3255 
smp_fetch_const_bin(const struct arg * args,struct sample * smp,const char * kw,void * private)3256 static int smp_fetch_const_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
3257 {
3258 	smp->flags |= SMP_F_CONST;
3259 	smp->data.type = SMP_T_BIN;
3260 	smp->data.u.str.area = args[0].data.str.area;
3261 	smp->data.u.str.data = args[0].data.str.data;
3262 	return 1;
3263 }
3264 
smp_check_const_meth(struct arg * args,char ** err)3265 static int smp_check_const_meth(struct arg *args, char **err)
3266 {
3267 	enum http_meth_t meth;
3268 	int i;
3269 
3270 	meth = find_http_meth(args[0].data.str.area, args[0].data.str.data);
3271 	if (meth != HTTP_METH_OTHER) {
3272 		args[0].type = ARGT_SINT;
3273 		args[0].data.sint = meth;
3274 	} else {
3275 		/* Check method avalaibility. A methos is a token defined as :
3276 		 * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
3277 		 *         "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
3278 		 * token = 1*tchar
3279 		 */
3280 		for (i = 0; i < args[0].data.str.data; i++) {
3281 			if (!HTTP_IS_TOKEN(args[0].data.str.area[i])) {
3282 				memprintf(err, "expects valid method.");
3283 				return 0;
3284 			}
3285 		}
3286 	}
3287 	return 1;
3288 }
3289 
smp_fetch_const_meth(const struct arg * args,struct sample * smp,const char * kw,void * private)3290 static int smp_fetch_const_meth(const struct arg *args, struct sample *smp, const char *kw, void *private)
3291 {
3292 	smp->data.type = SMP_T_METH;
3293 	if (args[0].type == ARGT_SINT) {
3294 		smp->flags &= ~SMP_F_CONST;
3295 		smp->data.u.meth.meth = args[0].data.sint;
3296 		smp->data.u.meth.str.area = "";
3297 		smp->data.u.meth.str.data = 0;
3298 	} else {
3299 		smp->flags |= SMP_F_CONST;
3300 		smp->data.u.meth.meth = HTTP_METH_OTHER;
3301 		smp->data.u.meth.str.area = args[0].data.str.area;
3302 		smp->data.u.meth.str.data = args[0].data.str.data;
3303 	}
3304 	return 1;
3305 }
3306 
3307 // This function checks the "uuid" sample's arguments.
3308 // Function won't get called when no parameter is specified (maybe a bug?)
smp_check_uuid(struct arg * args,char ** err)3309 static int smp_check_uuid(struct arg *args, char **err)
3310 {
3311 	if (!args[0].type) {
3312 		args[0].type = ARGT_SINT;
3313 		args[0].data.sint = 4;
3314 	}
3315 	else if (args[0].data.sint != 4) {
3316 		memprintf(err, "Unsupported UUID version: '%lld'", args[0].data.sint);
3317 		return 0;
3318 	}
3319 
3320 	return 1;
3321 }
3322 
3323 // Generate a RFC4122 UUID (default is v4 = fully random)
smp_fetch_uuid(const struct arg * args,struct sample * smp,const char * kw,void * private)3324 static int smp_fetch_uuid(const struct arg *args, struct sample *smp, const char *kw, void *private)
3325 {
3326 	if (args[0].data.sint == 4 || !args[0].type) {
3327 		uint32_t rnd[4] = { 0, 0, 0, 0 };
3328 		uint64_t last = 0;
3329 		int byte = 0;
3330 		uint8_t bits = 0;
3331 		unsigned int rand_max_bits = my_flsl(RAND_MAX);
3332 
3333 		while (byte < 4) {
3334 			while (bits < 32) {
3335 				last |= (uint64_t)ha_random() << bits;
3336 				bits += rand_max_bits;
3337 			}
3338 			rnd[byte++] = last;
3339 			last >>= 32u;
3340 			bits  -= 32;
3341 		}
3342 
3343 		chunk_printf(&trash, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12llx",
3344 			     rnd[0],
3345 			     rnd[1] & 0xFFFF,
3346 			     ((rnd[1] >> 16u) & 0xFFF) | 0x4000,  // highest 4 bits indicate the uuid version
3347 			     (rnd[2] & 0x3FFF) | 0x8000,  // the highest 2 bits indicate the UUID variant (10),
3348 			     (long long)((rnd[2] >> 14u) | ((uint64_t) rnd[3] << 18u)) & 0xFFFFFFFFFFFFull
3349 			);
3350 
3351 		smp->data.type = SMP_T_STR;
3352 		smp->flags = SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
3353 		smp->data.u.str = trash;
3354 		return 1;
3355 	}
3356 
3357 	// more implementations of other uuid formats possible here
3358 	return 0;
3359 }
3360 
3361 /* Note: must not be declared <const> as its list will be overwritten.
3362  * Note: fetches that may return multiple types must be declared as the lowest
3363  * common denominator, the type that can be casted into all other ones. For
3364  * instance IPv4/IPv6 must be declared IPv4.
3365  */
3366 static struct sample_fetch_kw_list smp_kws = {ILH, {
3367 	{ "always_false", smp_fetch_false, 0,            NULL, SMP_T_BOOL, SMP_USE_INTRN },
3368 	{ "always_true",  smp_fetch_true,  0,            NULL, SMP_T_BOOL, SMP_USE_INTRN },
3369 	{ "env",          smp_fetch_env,   ARG1(1,STR),  NULL, SMP_T_STR,  SMP_USE_INTRN },
3370 	{ "date",         smp_fetch_date,  ARG2(0,SINT,STR), smp_check_date_unit, SMP_T_SINT, SMP_USE_INTRN },
3371 	{ "date_us",      smp_fetch_date_us,  0,         NULL, SMP_T_SINT, SMP_USE_INTRN },
3372 	{ "hostname",     smp_fetch_hostname, 0,         NULL, SMP_T_STR,  SMP_USE_INTRN },
3373 	{ "nbproc",       smp_fetch_nbproc,0,            NULL, SMP_T_SINT, SMP_USE_INTRN },
3374 	{ "proc",         smp_fetch_proc,  0,            NULL, SMP_T_SINT, SMP_USE_INTRN },
3375 	{ "thread",       smp_fetch_thread,  0,          NULL, SMP_T_SINT, SMP_USE_INTRN },
3376 	{ "rand",         smp_fetch_rand,  ARG1(0,SINT), NULL, SMP_T_SINT, SMP_USE_INTRN },
3377 	{ "stopping",     smp_fetch_stopping, 0,         NULL, SMP_T_BOOL, SMP_USE_INTRN },
3378 	{ "stopping",     smp_fetch_stopping, 0,         NULL, SMP_T_BOOL, SMP_USE_INTRN },
3379 	{ "uuid",         smp_fetch_uuid,  ARG1(0, SINT),      smp_check_uuid, SMP_T_STR, SMP_USE_INTRN },
3380 
3381 	{ "cpu_calls",    smp_fetch_cpu_calls,  0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3382 	{ "cpu_ns_avg",   smp_fetch_cpu_ns_avg, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3383 	{ "cpu_ns_tot",   smp_fetch_cpu_ns_tot, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3384 	{ "lat_ns_avg",   smp_fetch_lat_ns_avg, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3385 	{ "lat_ns_tot",   smp_fetch_lat_ns_tot, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3386 
3387 	{ "str",  smp_fetch_const_str,  ARG1(1,STR),  NULL                , SMP_T_STR,  SMP_USE_INTRN },
3388 	{ "bool", smp_fetch_const_bool, ARG1(1,STR),  smp_check_const_bool, SMP_T_BOOL, SMP_USE_INTRN },
3389 	{ "int",  smp_fetch_const_int,  ARG1(1,SINT), NULL                , SMP_T_SINT, SMP_USE_INTRN },
3390 	{ "ipv4", smp_fetch_const_ipv4, ARG1(1,IPV4), NULL                , SMP_T_IPV4, SMP_USE_INTRN },
3391 	{ "ipv6", smp_fetch_const_ipv6, ARG1(1,IPV6), NULL                , SMP_T_IPV6, SMP_USE_INTRN },
3392 	{ "bin",  smp_fetch_const_bin,  ARG1(1,STR),  smp_check_const_bin , SMP_T_BIN,  SMP_USE_INTRN },
3393 	{ "meth", smp_fetch_const_meth, ARG1(1,STR),  smp_check_const_meth, SMP_T_METH, SMP_USE_INTRN },
3394 
3395 	{ /* END */ },
3396 }};
3397 
3398 INITCALL1(STG_REGISTER, sample_register_fetches, &smp_kws);
3399 
3400 /* Note: must not be declared <const> as its list will be overwritten */
3401 static struct sample_conv_kw_list sample_conv_kws = {ILH, {
3402 	{ "debug",  sample_conv_debug,     ARG2(0,STR,STR), smp_check_debug, SMP_T_ANY,  SMP_T_ANY },
3403 	{ "b64dec", sample_conv_base642bin,0,            NULL, SMP_T_STR,  SMP_T_BIN  },
3404 	{ "base64", sample_conv_bin2base64,0,            NULL, SMP_T_BIN,  SMP_T_STR  },
3405 	{ "upper",  sample_conv_str2upper, 0,            NULL, SMP_T_STR,  SMP_T_STR  },
3406 	{ "lower",  sample_conv_str2lower, 0,            NULL, SMP_T_STR,  SMP_T_STR  },
3407 	{ "length", sample_conv_length,    0,            NULL, SMP_T_STR,  SMP_T_SINT },
3408 	{ "hex",    sample_conv_bin2hex,   0,            NULL, SMP_T_BIN,  SMP_T_STR  },
3409 	{ "hex2i",  sample_conv_hex2int,   0,            NULL, SMP_T_STR,  SMP_T_SINT },
3410 	{ "ipmask", sample_conv_ipmask,    ARG2(1,MSK4,MSK6), NULL, SMP_T_ADDR, SMP_T_IPV4 },
3411 	{ "ltime",  sample_conv_ltime,     ARG2(1,STR,SINT), NULL, SMP_T_SINT, SMP_T_STR },
3412 	{ "utime",  sample_conv_utime,     ARG2(1,STR,SINT), NULL, SMP_T_SINT, SMP_T_STR },
3413 	{ "crc32",  sample_conv_crc32,     ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3414 	{ "crc32c", sample_conv_crc32c,    ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3415 	{ "djb2",   sample_conv_djb2,      ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3416 	{ "sdbm",   sample_conv_sdbm,      ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3417 	{ "wt6",    sample_conv_wt6,       ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3418 	{ "xxh32",  sample_conv_xxh32,     ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3419 	{ "xxh64",  sample_conv_xxh64,     ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3420 	{ "json",   sample_conv_json,      ARG1(1,STR),  sample_conv_json_check, SMP_T_STR,  SMP_T_STR },
3421 	{ "bytes",  sample_conv_bytes,     ARG2(1,SINT,SINT), NULL, SMP_T_BIN,  SMP_T_BIN },
3422 	{ "field",  sample_conv_field,     ARG3(2,SINT,STR,SINT), sample_conv_field_check, SMP_T_STR,  SMP_T_STR },
3423 	{ "word",   sample_conv_word,      ARG3(2,SINT,STR,SINT), sample_conv_field_check, SMP_T_STR,  SMP_T_STR },
3424 	{ "regsub", sample_conv_regsub,    ARG3(2,REG,STR,STR), sample_conv_regsub_check, SMP_T_STR, SMP_T_STR },
3425 	{ "sha1",   sample_conv_sha1,      0,            NULL, SMP_T_BIN,  SMP_T_BIN  },
3426 #ifdef USE_OPENSSL
3427 	{ "sha2",   sample_conv_sha2,      ARG1(0, SINT), smp_check_sha2, SMP_T_BIN,  SMP_T_BIN  },
3428 #endif
3429 	{ "concat", sample_conv_concat,    ARG3(1,STR,STR,STR), smp_check_concat, SMP_T_STR,  SMP_T_STR },
3430 	{ "strcmp", sample_conv_strcmp,    ARG1(1,STR), smp_check_strcmp, SMP_T_STR,  SMP_T_SINT },
3431 
3432 	/* gRPC converters. */
3433 	{ "ungrpc", sample_conv_ungrpc,    ARG2(1,PBUF_FNUM,STR), sample_conv_protobuf_check, SMP_T_BIN, SMP_T_BIN  },
3434 	{ "protobuf", sample_conv_protobuf, ARG2(1,PBUF_FNUM,STR), sample_conv_protobuf_check, SMP_T_BIN, SMP_T_BIN  },
3435 
3436 	{ "and",    sample_conv_binary_and, ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3437 	{ "or",     sample_conv_binary_or,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3438 	{ "xor",    sample_conv_binary_xor, ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3439 	{ "cpl",    sample_conv_binary_cpl,           0, NULL, SMP_T_SINT, SMP_T_SINT  },
3440 	{ "bool",   sample_conv_arith_bool,           0, NULL, SMP_T_SINT, SMP_T_BOOL },
3441 	{ "not",    sample_conv_arith_not,            0, NULL, SMP_T_SINT, SMP_T_BOOL },
3442 	{ "odd",    sample_conv_arith_odd,            0, NULL, SMP_T_SINT, SMP_T_BOOL },
3443 	{ "even",   sample_conv_arith_even,           0, NULL, SMP_T_SINT, SMP_T_BOOL },
3444 	{ "add",    sample_conv_arith_add,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3445 	{ "sub",    sample_conv_arith_sub,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3446 	{ "mul",    sample_conv_arith_mul,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3447 	{ "div",    sample_conv_arith_div,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3448 	{ "mod",    sample_conv_arith_mod,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3449 	{ "neg",    sample_conv_arith_neg,            0, NULL, SMP_T_SINT, SMP_T_SINT  },
3450 
3451 	{ NULL, NULL, 0, 0, 0 },
3452 }};
3453 
3454 INITCALL1(STG_REGISTER, sample_register_convs, &sample_conv_kws);
3455