~ubuntu-branches/debian/stretch/haproxy/stretch

« back to all changes in this revision

Viewing changes to src/pattern.c

  • Committer: Package Import Robot
  • Author(s): Apollon Oikonomopoulos
  • Date: 2014-06-20 11:05:17 UTC
  • mfrom: (1.1.15) (15.1.12 experimental)
  • Revision ID: package-import@ubuntu.com-20140620110517-u6q5p9kyy2f3ozw9
Tags: 1.5.0-1
* New upstream stable series. Notable changes since the 1.4 series:
  + Native SSL support on both sides with SNI/NPN/ALPN and OCSP stapling.
  + IPv6 and UNIX sockets are supported everywhere
  + End-to-end HTTP keep-alive for better support of NTLM and improved
    efficiency in static farms
  + HTTP/1.1 response compression (deflate, gzip) to save bandwidth
  + PROXY protocol versions 1 and 2 on both sides
  + Data sampling on everything in request or response, including payload
  + ACLs can use any matching method with any input sample
  + Maps and dynamic ACLs updatable from the CLI
  + Stick-tables support counters to track activity on any input sample
  + Custom format for logs, unique-id, header rewriting, and redirects
  + Improved health checks (SSL, scripted TCP, check agent, ...)
  + Much more scalable configuration supports hundreds of thousands of
    backends and certificates without sweating

* Upload to unstable, merge all 1.5 work from experimental. Most important
  packaging changes since 1.4.25-1 include:
  + systemd support.
  + A more sane default config file.
  + Zero-downtime upgrades between 1.5 releases by gracefully reloading
    HAProxy during upgrades.
  + HTML documentation shipped in the haproxy-doc package.
  + kqueue support for kfreebsd.

* Packaging changes since 1.5~dev26-2:
  + Drop patches merged upstream:
    o Fix-reference-location-in-manpage.patch
    o 0001-BUILD-stats-workaround-stupid-and-bogus-Werror-forma.patch
  + d/watch: look for stable 1.5 releases
  + systemd: respect CONFIG and EXTRAOPTS when specified in
    /etc/default/haproxy.
  + initscript: test the configuration before start or reload.
  + initscript: remove the ENABLED flag and logic.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Patterns management functions.
 
2
 * Pattern management functions.
3
3
 *
4
 
 * Copyright 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
 
4
 * Copyright 2000-2013 Willy Tarreau <w@1wt.eu>
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or
7
7
 * modify it under the terms of the GNU General Public License
10
10
 *
11
11
 */
12
12
 
13
 
#include <string.h>
14
 
#include <arpa/inet.h>
15
 
#include <types/stick_table.h>
16
 
 
 
13
#include <ctype.h>
 
14
#include <stdio.h>
 
15
 
 
16
#include <common/config.h>
 
17
#include <common/standard.h>
 
18
 
 
19
#include <types/global.h>
 
20
#include <types/pattern.h>
 
21
 
 
22
#include <proto/log.h>
17
23
#include <proto/pattern.h>
18
 
#include <common/standard.h>
19
 
 
20
 
/* static structure used on pattern_process if <p> is NULL*/
21
 
static struct pattern spattern;
22
 
 
23
 
/* trash chunk used for pattern conversions */
24
 
static struct chunk trash_chunk;
25
 
 
26
 
/* trash buffers used or pattern conversions */
27
 
static char pattern_trash_buf1[BUFSIZE];
28
 
static char pattern_trash_buf2[BUFSIZE];
29
 
 
30
 
/* pattern_trash_buf point on used buffer*/
31
 
static char *pattern_trash_buf = pattern_trash_buf1;
32
 
 
33
 
/* static structure used to returns builded table key from a pattern*/
34
 
static struct stktable_key stable_key;
35
 
 
36
 
/* list head of all known pattern fetch keywords */
37
 
static struct pattern_fetch_kw_list pattern_fetches = {
38
 
        .list = LIST_HEAD_INIT(pattern_fetches.list)
39
 
};
40
 
 
41
 
/* list head of all known pattern format conversion keywords */
42
 
static struct pattern_conv_kw_list pattern_convs = {
43
 
        .list = LIST_HEAD_INIT(pattern_convs.list)
44
 
};
45
 
 
46
 
/*
47
 
 * Registers the pattern fetch keyword list <kwl> as a list of valid keywords for next
48
 
 * parsing sessions.
49
 
 */
50
 
void pattern_register_fetches(struct pattern_fetch_kw_list *pfkl)
51
 
{
52
 
        LIST_ADDQ(&pattern_fetches.list, &pfkl->list);
53
 
}
54
 
 
55
 
/*
56
 
 * Registers the pattern format coverstion keyword list <pckl> as a list of valid keywords for next
57
 
 * parsing sessions.
58
 
 */
59
 
void pattern_register_convs(struct pattern_conv_kw_list *pckl)
60
 
{
61
 
        LIST_ADDQ(&pattern_convs.list, &pckl->list);
62
 
}
63
 
 
64
 
/*
65
 
 * Returns the pointer on pattern fetch keyword structure identified by
66
 
 * string of <len> in buffer <kw>.
67
 
 *
68
 
 */
69
 
struct pattern_fetch *find_pattern_fetch(const char *kw, int len)
70
 
{
71
 
        int index;
72
 
        struct pattern_fetch_kw_list *kwl;
73
 
 
74
 
        list_for_each_entry(kwl, &pattern_fetches.list, list) {
75
 
                for (index = 0; kwl->kw[index].kw != NULL; index++) {
76
 
                        if (strncmp(kwl->kw[index].kw, kw, len) == 0 &&
77
 
                            kwl->kw[index].kw[len] == '\0')
78
 
                                return &kwl->kw[index];
79
 
                }
80
 
        }
81
 
        return NULL;
82
 
}
83
 
 
84
 
/*
85
 
 * Returns the pointer on pattern format conversion keyword structure identified by
86
 
 * string of <len> in buffer <kw>.
87
 
 *
88
 
 */
89
 
struct pattern_conv *find_pattern_conv(const char *kw, int len)
90
 
{
91
 
        int index;
92
 
        struct pattern_conv_kw_list *kwl;
93
 
 
94
 
        list_for_each_entry(kwl, &pattern_convs.list, list) {
95
 
                for (index = 0; kwl->kw[index].kw != NULL; index++) {
96
 
                        if (strncmp(kwl->kw[index].kw, kw, len) == 0 &&
97
 
                            kwl->kw[index].kw[len] == '\0')
98
 
                                return &kwl->kw[index];
99
 
                }
100
 
        }
101
 
        return NULL;
102
 
}
103
 
 
104
 
 
105
 
/*
106
 
* Returns a static trash struct chunk to use in pattern casts or format conversions
107
 
* Swiths the 2 available trash buffers to protect data during convert
108
 
*/
109
 
static struct chunk *get_trash_chunk(void)
110
 
{
111
 
        if (pattern_trash_buf == pattern_trash_buf1)
112
 
                pattern_trash_buf = pattern_trash_buf2;
113
 
        else
114
 
                pattern_trash_buf = pattern_trash_buf1;
115
 
 
116
 
        trash_chunk.str = pattern_trash_buf;
117
 
        trash_chunk.len = 0;
118
 
        trash_chunk.size = BUFSIZE;
119
 
 
120
 
        return &trash_chunk;
121
 
}
122
 
 
123
 
/*
124
 
* Used to set pattern data from a struct chunk, could be the trash struct chunk
125
 
*/
126
 
static void pattern_data_setstring(union pattern_data *data, struct chunk *c)
127
 
{
128
 
        data->str.str = c->str;
129
 
        data->str.len = c->len;
130
 
        data->str.size = c->size;
131
 
}
132
 
 
133
 
/******************************************************************/
134
 
/*          Pattern casts functions                               */
135
 
/******************************************************************/
136
 
 
137
 
static int c_ip2int(union pattern_data *data)
138
 
{
139
 
        data->integer = ntohl(data->ip.s_addr);
140
 
        return 1;
141
 
}
142
 
 
143
 
static int c_ip2str(union pattern_data *data)
144
 
{
145
 
        struct chunk *trash = get_trash_chunk();
146
 
 
147
 
        if (!inet_ntop(AF_INET, (void *)&data->ip, trash->str, trash->size))
148
 
                return 0;
149
 
 
150
 
        trash->len = strlen(trash->str);
151
 
        pattern_data_setstring(data, trash);
152
 
 
153
 
        return 1;
154
 
}
155
 
 
156
 
static int c_int2ip(union pattern_data *data)
157
 
{
158
 
        data->ip.s_addr = htonl(data->integer);
159
 
        return 1;
160
 
}
161
 
 
162
 
/* Convert a fixed-length string to an IP address. Returns 0 in case of error,
163
 
 * or the number of chars read in case of success.
164
 
 */
165
 
static int buf2ip(const char *buf, size_t len, struct in_addr *dst)
166
 
{
167
 
        const char *addr;
168
 
        int saw_digit, octets, ch;
169
 
        u_char tmp[4], *tp;
170
 
        const char *cp = buf;
171
 
 
172
 
        saw_digit = 0;
173
 
        octets = 0;
174
 
        *(tp = tmp) = 0;
175
 
 
176
 
        for (addr = buf; addr - buf < len; addr++) {
177
 
                unsigned char digit = (ch = *addr) - '0';
178
 
 
179
 
                if (digit > 9 && ch != '.')
180
 
                        break;
181
 
 
182
 
                if (digit <= 9) {
183
 
                        u_int new = *tp * 10 + digit;
184
 
 
185
 
                        if (new > 255)
186
 
                                return 0;
187
 
 
188
 
                        *tp = new;
189
 
 
190
 
                        if (!saw_digit) {
191
 
                                if (++octets > 4)
192
 
                                        return 0;
193
 
                                saw_digit = 1;
194
 
                        }
195
 
                } else if (ch == '.' && saw_digit) {
196
 
                        if (octets == 4)
197
 
                                return 0;
198
 
 
199
 
                        *++tp = 0;
200
 
                        saw_digit = 0;
201
 
                } else
202
 
                        return 0;
203
 
        }
204
 
 
205
 
        if (octets < 4)
206
 
                return 0;
207
 
 
208
 
        memcpy(&dst->s_addr, tmp, 4);
209
 
        return addr - cp;
210
 
}
211
 
 
212
 
static int c_str2ip(union pattern_data *data)
213
 
{
214
 
        if (!buf2ip(data->str.str, data->str.len, &data->ip))
215
 
                return 0;
216
 
        return 1;
217
 
}
218
 
 
219
 
static int c_int2str(union pattern_data *data)
220
 
{
221
 
        struct chunk *trash = get_trash_chunk();
222
 
        char *pos;
223
 
 
224
 
        pos = ultoa_r(data->integer, trash->str, trash->size);
225
 
 
226
 
        if (!pos)
227
 
                return 0;
228
 
 
229
 
        trash->str = pos;
230
 
        trash->len = strlen(pos);
231
 
 
232
 
        pattern_data_setstring(data, trash);
233
 
 
234
 
        return 1;
235
 
}
236
 
 
237
 
static int c_donothing(union pattern_data *data)
238
 
{
239
 
        return 1;
240
 
}
241
 
 
242
 
static int c_str2int(union pattern_data *data)
243
 
{
244
 
        int i;
245
 
        uint32_t ret = 0;
246
 
 
247
 
        for (i = 0; i < data->str.len; i++) {
248
 
                uint32_t val = data->str.str[i] - '0';
249
 
 
250
 
                if (val > 9)
251
 
                        break;
252
 
 
253
 
                ret = ret * 10 + val;
254
 
        }
255
 
 
256
 
        data->integer = ret;
257
 
        return 1;
258
 
}
259
 
 
260
 
/*****************************************************************/
261
 
/*      Pattern casts matrix:                                    */
262
 
/*           pattern_casts[from type][to type]                   */
263
 
/*           NULL pointer used for impossible pattern casts      */
264
 
/*****************************************************************/
265
 
 
266
 
typedef int (*pattern_cast)(union pattern_data *data);
267
 
static pattern_cast pattern_casts[PATTERN_TYPES][PATTERN_TYPES] = { { c_donothing, c_ip2int, c_ip2str  },
268
 
                                                                    { c_int2ip, c_donothing, c_int2str },
269
 
                                                                    { c_str2ip, c_str2int, c_donothing } };
270
 
 
271
 
 
272
 
/*****************************************************************/
273
 
/*    typed pattern to typed table key functions                 */
274
 
/*****************************************************************/
275
 
 
276
 
static void *k_int2int(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len)
277
 
{
278
 
        return (void *)&pdata->integer;
279
 
}
280
 
 
281
 
static void *k_ip2ip(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len)
282
 
{
283
 
        return (void *)&pdata->ip.s_addr;
284
 
}
285
 
 
286
 
static void *k_ip2int(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len)
287
 
{
288
 
        kdata->integer = ntohl(pdata->ip.s_addr);
289
 
        return (void *)&kdata->integer;
290
 
}
291
 
 
292
 
static void *k_int2ip(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len)
293
 
{
294
 
        kdata->ip.s_addr = htonl(pdata->integer);
295
 
        return (void *)&kdata->ip.s_addr;
296
 
}
297
 
 
298
 
static void *k_str2str(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len)
299
 
{
300
 
        *len = pdata->str.len;
301
 
        return (void *)pdata->str.str;
302
 
}
303
 
 
304
 
static void *k_ip2str(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len)
305
 
{
306
 
        if (!inet_ntop(AF_INET, &pdata->ip, kdata->buf, sizeof(kdata->buf)))
307
 
                return NULL;
308
 
 
309
 
        *len = strlen((const char *)kdata->buf);
310
 
        return (void *)kdata->buf;
311
 
}
312
 
 
313
 
static void *k_int2str(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len)
314
 
{
315
 
        void *key;
316
 
 
317
 
        key = (void *)ultoa_r(pdata->integer,  kdata->buf,  sizeof(kdata->buf));
318
 
        if (!key)
319
 
                return NULL;
320
 
 
321
 
        *len = strlen((const char *)key);
322
 
        return key;
323
 
}
324
 
 
325
 
static void *k_str2ip(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len)
326
 
{
327
 
        if (!buf2ip(pdata->str.str, pdata->str.len, &kdata->ip))
328
 
                return NULL;
329
 
 
330
 
        return (void *)&kdata->ip.s_addr;
331
 
}
332
 
 
333
 
 
334
 
static void *k_str2int(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len)
335
 
{
336
 
        int i;
337
 
 
338
 
        kdata->integer = 0;
339
 
        for (i = 0; i < pdata->str.len; i++) {
340
 
                uint32_t val = pdata->str.str[i] - '0';
341
 
 
342
 
                if (val > 9)
343
 
                        break;
344
 
 
345
 
                kdata->integer = kdata->integer * 10 + val;
346
 
        }
347
 
        return (void *)&kdata->integer;
348
 
}
349
 
 
350
 
/*****************************************************************/
351
 
/*      typed pattern to typed table key matrix:                 */
352
 
/*           pattern_keys[from pattern type][to table key type]  */
353
 
/*           NULL pointer used for impossible pattern casts      */
354
 
/*****************************************************************/
355
 
 
356
 
typedef void *(*pattern_key)(union pattern_data *pdata, union stktable_key_data *kdata, size_t *len);
357
 
static pattern_key pattern_keys[PATTERN_TYPES][STKTABLE_TYPES] = { { k_ip2ip,  k_ip2int,  k_ip2str  },
358
 
                                                                   { k_int2ip, k_int2int, k_int2str },
359
 
                                                                   { k_str2ip, k_str2int, k_str2str } };
360
 
/*
361
 
 * Parse a pattern expression configuration:
362
 
 *        fetch keyword followed by format conversion keywords.
363
 
 * Returns a pointer on allocated pattern expression structure.
364
 
 */
365
 
struct pattern_expr *pattern_parse_expr(char **str, int *idx)
366
 
{
367
 
        const char *endw;
368
 
        const char *end;
369
 
        struct pattern_expr *expr;
370
 
        struct pattern_fetch *fetch;
371
 
        struct pattern_conv *conv;
372
 
        unsigned long prev_type;
373
 
 
374
 
        if (!str[*idx])
375
 
                goto out_error;
376
 
 
377
 
        end = str[*idx] + strlen(str[*idx]);
378
 
        endw = strchr(str[*idx], '(');
379
 
 
380
 
        if (!endw)
381
 
                endw = end;
382
 
        else if ((end-1)[0] != ')')
383
 
                goto out_error;
384
 
 
385
 
        fetch = find_pattern_fetch(str[*idx], endw - str[*idx]);
386
 
        if (!fetch)
387
 
                goto out_error;
388
 
 
389
 
        if (fetch->out_type >= PATTERN_TYPES)
390
 
                goto out_error;
391
 
 
392
 
        prev_type = fetch->out_type;
393
 
        expr = calloc(1, sizeof(struct pattern_expr));
394
 
 
395
 
        LIST_INIT(&(expr->conv_exprs));
396
 
        expr->fetch = fetch;
397
 
 
398
 
        if (end != endw) {
399
 
                expr->arg_len = end - endw - 2;
400
 
                expr->arg = my_strndup(endw + 1, expr->arg_len);
401
 
        }
402
 
 
403
 
        for (*idx += 1; *(str[*idx]); (*idx)++) {
404
 
                struct pattern_conv_expr *conv_expr;
405
 
 
406
 
                end = str[*idx] + strlen(str[*idx]);
407
 
                endw = strchr(str[*idx], '(');
408
 
 
409
 
                if (!endw)
410
 
                        endw = end;
411
 
                else if ((end-1)[0] != ')')
412
 
                        goto out_error;
413
 
 
414
 
                conv = find_pattern_conv(str[*idx], endw - str[*idx]);
415
 
                if (!conv)
416
 
                        break;
417
 
 
418
 
                if (conv->in_type >= PATTERN_TYPES ||
419
 
                    conv->out_type >= PATTERN_TYPES)
420
 
                        goto out_error;
421
 
 
422
 
                /* If impossible type conversion */
423
 
                if (!pattern_casts[prev_type][conv->in_type])
424
 
                        goto out_error;
425
 
 
426
 
                prev_type = conv->out_type;
427
 
                conv_expr = calloc(1, sizeof(struct pattern_conv_expr));
428
 
 
429
 
                LIST_ADDQ(&(expr->conv_exprs), &(conv_expr->list));
430
 
                conv_expr->conv = conv;
431
 
 
432
 
                if (end != endw) {
433
 
                        int i = end - endw - 2;
434
 
                        char *p = my_strndup(endw + 1, i);
435
 
 
436
 
                        if (conv->parse_args) {
437
 
                                i = conv->parse_args(p, &conv_expr->arg_p, &conv_expr->arg_i);
438
 
                                free(p);
439
 
                                if (!i)
440
 
                                        goto out_error;
441
 
                        } else {
442
 
                                conv_expr->arg_i = i;
443
 
                                conv_expr->arg_p = p;
444
 
                        }
445
 
                }
446
 
        }
 
24
#include <proto/sample.h>
 
25
 
 
26
#include <ebsttree.h>
 
27
 
 
28
char *pat_match_names[PAT_MATCH_NUM] = {
 
29
        [PAT_MATCH_FOUND] = "found",
 
30
        [PAT_MATCH_BOOL]  = "bool",
 
31
        [PAT_MATCH_INT]   = "int",
 
32
        [PAT_MATCH_IP]    = "ip",
 
33
        [PAT_MATCH_BIN]   = "bin",
 
34
        [PAT_MATCH_LEN]   = "len",
 
35
        [PAT_MATCH_STR]   = "str",
 
36
        [PAT_MATCH_BEG]   = "beg",
 
37
        [PAT_MATCH_SUB]   = "sub",
 
38
        [PAT_MATCH_DIR]   = "dir",
 
39
        [PAT_MATCH_DOM]   = "dom",
 
40
        [PAT_MATCH_END]   = "end",
 
41
        [PAT_MATCH_REG]   = "reg",
 
42
};
 
43
 
 
44
int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, int, char **) = {
 
45
        [PAT_MATCH_FOUND] = pat_parse_nothing,
 
46
        [PAT_MATCH_BOOL]  = pat_parse_nothing,
 
47
        [PAT_MATCH_INT]   = pat_parse_int,
 
48
        [PAT_MATCH_IP]    = pat_parse_ip,
 
49
        [PAT_MATCH_BIN]   = pat_parse_bin,
 
50
        [PAT_MATCH_LEN]   = pat_parse_int,
 
51
        [PAT_MATCH_STR]   = pat_parse_str,
 
52
        [PAT_MATCH_BEG]   = pat_parse_str,
 
53
        [PAT_MATCH_SUB]   = pat_parse_str,
 
54
        [PAT_MATCH_DIR]   = pat_parse_str,
 
55
        [PAT_MATCH_DOM]   = pat_parse_str,
 
56
        [PAT_MATCH_END]   = pat_parse_str,
 
57
        [PAT_MATCH_REG]   = pat_parse_reg,
 
58
};
 
59
 
 
60
int (*pat_index_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pattern *, char **) = {
 
61
        [PAT_MATCH_FOUND] = pat_idx_list_val,
 
62
        [PAT_MATCH_BOOL]  = pat_idx_list_val,
 
63
        [PAT_MATCH_INT]   = pat_idx_list_val,
 
64
        [PAT_MATCH_IP]    = pat_idx_tree_ip,
 
65
        [PAT_MATCH_BIN]   = pat_idx_list_ptr,
 
66
        [PAT_MATCH_LEN]   = pat_idx_list_val,
 
67
        [PAT_MATCH_STR]   = pat_idx_tree_str,
 
68
        [PAT_MATCH_BEG]   = pat_idx_tree_pfx,
 
69
        [PAT_MATCH_SUB]   = pat_idx_list_str,
 
70
        [PAT_MATCH_DIR]   = pat_idx_list_str,
 
71
        [PAT_MATCH_DOM]   = pat_idx_list_str,
 
72
        [PAT_MATCH_END]   = pat_idx_list_str,
 
73
        [PAT_MATCH_REG]   = pat_idx_list_reg,
 
74
};
 
75
 
 
76
void (*pat_delete_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pat_ref_elt *) = {
 
77
        [PAT_MATCH_FOUND] = pat_del_list_val,
 
78
        [PAT_MATCH_BOOL]  = pat_del_list_val,
 
79
        [PAT_MATCH_INT]   = pat_del_list_val,
 
80
        [PAT_MATCH_IP]    = pat_del_tree_ip,
 
81
        [PAT_MATCH_BIN]   = pat_del_list_ptr,
 
82
        [PAT_MATCH_LEN]   = pat_del_list_val,
 
83
        [PAT_MATCH_STR]   = pat_del_tree_str,
 
84
        [PAT_MATCH_BEG]   = pat_del_tree_str,
 
85
        [PAT_MATCH_SUB]   = pat_del_list_ptr,
 
86
        [PAT_MATCH_DIR]   = pat_del_list_ptr,
 
87
        [PAT_MATCH_DOM]   = pat_del_list_ptr,
 
88
        [PAT_MATCH_END]   = pat_del_list_ptr,
 
89
        [PAT_MATCH_REG]   = pat_del_list_reg,
 
90
};
 
91
 
 
92
void (*pat_prune_fcts[PAT_MATCH_NUM])(struct pattern_expr *) = {
 
93
        [PAT_MATCH_FOUND] = pat_prune_val,
 
94
        [PAT_MATCH_BOOL]  = pat_prune_val,
 
95
        [PAT_MATCH_INT]   = pat_prune_val,
 
96
        [PAT_MATCH_IP]    = pat_prune_val,
 
97
        [PAT_MATCH_BIN]   = pat_prune_ptr,
 
98
        [PAT_MATCH_LEN]   = pat_prune_val,
 
99
        [PAT_MATCH_STR]   = pat_prune_ptr,
 
100
        [PAT_MATCH_BEG]   = pat_prune_ptr,
 
101
        [PAT_MATCH_SUB]   = pat_prune_ptr,
 
102
        [PAT_MATCH_DIR]   = pat_prune_ptr,
 
103
        [PAT_MATCH_DOM]   = pat_prune_ptr,
 
104
        [PAT_MATCH_END]   = pat_prune_ptr,
 
105
        [PAT_MATCH_REG]   = pat_prune_reg,
 
106
};
 
107
 
 
108
struct pattern *(*pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern_expr *, int) = {
 
109
        [PAT_MATCH_FOUND] = NULL,
 
110
        [PAT_MATCH_BOOL]  = pat_match_nothing,
 
111
        [PAT_MATCH_INT]   = pat_match_int,
 
112
        [PAT_MATCH_IP]    = pat_match_ip,
 
113
        [PAT_MATCH_BIN]   = pat_match_bin,
 
114
        [PAT_MATCH_LEN]   = pat_match_len,
 
115
        [PAT_MATCH_STR]   = pat_match_str,
 
116
        [PAT_MATCH_BEG]   = pat_match_beg,
 
117
        [PAT_MATCH_SUB]   = pat_match_sub,
 
118
        [PAT_MATCH_DIR]   = pat_match_dir,
 
119
        [PAT_MATCH_DOM]   = pat_match_dom,
 
120
        [PAT_MATCH_END]   = pat_match_end,
 
121
        [PAT_MATCH_REG]   = pat_match_reg,
 
122
};
 
123
 
 
124
/* Just used for checking configuration compatibility */
 
125
int pat_match_types[PAT_MATCH_NUM] = {
 
126
        [PAT_MATCH_FOUND] = SMP_T_UINT,
 
127
        [PAT_MATCH_BOOL]  = SMP_T_UINT,
 
128
        [PAT_MATCH_INT]   = SMP_T_UINT,
 
129
        [PAT_MATCH_IP]    = SMP_T_ADDR,
 
130
        [PAT_MATCH_BIN]   = SMP_T_BIN,
 
131
        [PAT_MATCH_LEN]   = SMP_T_STR,
 
132
        [PAT_MATCH_STR]   = SMP_T_STR,
 
133
        [PAT_MATCH_BEG]   = SMP_T_STR,
 
134
        [PAT_MATCH_SUB]   = SMP_T_STR,
 
135
        [PAT_MATCH_DIR]   = SMP_T_STR,
 
136
        [PAT_MATCH_DOM]   = SMP_T_STR,
 
137
        [PAT_MATCH_END]   = SMP_T_STR,
 
138
        [PAT_MATCH_REG]   = SMP_T_STR,
 
139
};
 
140
 
 
141
/* this struct is used to return information */
 
142
static struct pattern static_pattern;
 
143
 
 
144
/* This is the root of the list of all pattern_ref avalaibles. */
 
145
struct list pattern_reference = LIST_HEAD_INIT(pattern_reference);
 
146
 
 
147
/*
 
148
 *
 
149
 * The following functions are not exported and are used by internals process
 
150
 * of pattern matching
 
151
 *
 
152
 */
 
153
 
 
154
/* Background: Fast way to find a zero byte in a word
 
155
 * http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
 
156
 * hasZeroByte = (v - 0x01010101UL) & ~v & 0x80808080UL;
 
157
 *
 
158
 * To look for 4 different byte values, xor the word with those bytes and
 
159
 * then check for zero bytes:
 
160
 *
 
161
 * v = (((unsigned char)c * 0x1010101U) ^ delimiter)
 
162
 * where <delimiter> is the 4 byte values to look for (as an uint)
 
163
 * and <c> is the character that is being tested
 
164
 */
 
165
static inline unsigned int is_delimiter(unsigned char c, unsigned int mask)
 
166
{
 
167
        mask ^= (c * 0x01010101); /* propagate the char to all 4 bytes */
 
168
        return (mask - 0x01010101) & ~mask & 0x80808080U;
 
169
}
 
170
 
 
171
static inline unsigned int make_4delim(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4)
 
172
{
 
173
        return d1 << 24 | d2 << 16 | d3 << 8 | d4;
 
174
}
 
175
 
 
176
 
 
177
/*
 
178
 *
 
179
 * These functions are exported and may be used by any other component.
 
180
 *
 
181
 * The following functions are used for parsing pattern matching
 
182
 * input value. The <text> contain the string to be parsed. <pattern>
 
183
 * must be a preallocated pattern. The pat_parse_* functions fill this
 
184
 * structure with the parsed value. <usage> can be PAT_U_COMPILE or
 
185
 * PAT_U_LOOKUP. If the value PAT_U_COMPILE is used memory is allocated
 
186
 * for filling the pattern. If the value PAT_U_LOOKUP is set, the parser
 
187
 * use "trash" or return pointers to the input strings. In both cases,
 
188
 * the caller must use the value PAT_U_LOOKUP with caution. <err> is
 
189
 * filled with an error message built with memprintf() function.
 
190
 *
 
191
 * In succes case, the pat_parse_* function return 1. If the function
 
192
 * fail, it returns 0 and <err> is filled.
 
193
 *
 
194
 */
 
195
 
 
196
/* ignore the current line */
 
197
int pat_parse_nothing(const char *text, struct pattern *pattern, int mflags, char **err)
 
198
{
 
199
        return 1;
 
200
}
 
201
 
 
202
/* Parse a string. It is allocated and duplicated. */
 
203
int pat_parse_str(const char *text, struct pattern *pattern, int mflags, char **err)
 
204
{
 
205
        pattern->type = SMP_T_STR;
 
206
        pattern->ptr.str = (char *)text;
 
207
        pattern->len = strlen(text);
 
208
        return 1;
 
209
}
 
210
 
 
211
/* Parse a binary written in hexa. It is allocated. */
 
212
int pat_parse_bin(const char *text, struct pattern *pattern, int mflags, char **err)
 
213
{
 
214
        struct chunk *trash;
 
215
 
 
216
        pattern->type = SMP_T_BIN;
 
217
        trash = get_trash_chunk();
 
218
        pattern->len = trash->size;
 
219
        pattern->ptr.str = trash->str;
 
220
        return !!parse_binary(text, &pattern->ptr.str, &pattern->len, err);
 
221
}
 
222
 
 
223
/* Parse a regex. It is allocated. */
 
224
int pat_parse_reg(const char *text, struct pattern *pattern, int mflags, char **err)
 
225
{
 
226
        struct chunk *trash;
 
227
 
 
228
        trash = get_trash_chunk();
 
229
        if (trash->size < sizeof(*pattern->ptr.reg)) {
 
230
                memprintf(err, "no space avalaible in the buffer. expect %d, provides %d",
 
231
                          (int)sizeof(*pattern->ptr.reg), trash->size);
 
232
                return 0;
 
233
        }
 
234
 
 
235
        pattern->ptr.str = (char *)text;
 
236
 
 
237
        return 1;
 
238
}
 
239
 
 
240
/* Parse a range of positive integers delimited by either ':' or '-'. If only
 
241
 * one integer is read, it is set as both min and max. An operator may be
 
242
 * specified as the prefix, among this list of 5 :
 
243
 *
 
244
 *    0:eq, 1:gt, 2:ge, 3:lt, 4:le
 
245
 *
 
246
 * The default operator is "eq". It supports range matching. Ranges are
 
247
 * rejected for other operators. The operator may be changed at any time.
 
248
 * The operator is stored in the 'opaque' argument.
 
249
 *
 
250
 * If err is non-NULL, an error message will be returned there on errors and
 
251
 * the caller will have to free it. The function returns zero on error, and
 
252
 * non-zero on success.
 
253
 *
 
254
 */
 
255
int pat_parse_int(const char *text, struct pattern *pattern, int mflags, char **err)
 
256
{
 
257
        const char *ptr = text;
 
258
 
 
259
        pattern->type = SMP_T_UINT;
 
260
 
 
261
        /* Empty string is not valid */
 
262
        if (!*text)
 
263
                goto not_valid_range;
 
264
 
 
265
        /* Search ':' or '-' separator. */
 
266
        while (*ptr != '\0' && *ptr != ':' && *ptr != '-')
 
267
                ptr++;
 
268
 
 
269
        /* If separator not found. */
 
270
        if (!*ptr) {
 
271
                if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0) {
 
272
                        memprintf(err, "'%s' is not a number", text);
 
273
                        return 0;
 
274
                }
 
275
                pattern->val.range.max = pattern->val.range.min;
 
276
                pattern->val.range.min_set = 1;
 
277
                pattern->val.range.max_set = 1;
 
278
                return 1;
 
279
        }
 
280
 
 
281
        /* If the separator is the first character. */
 
282
        if (ptr == text && *(ptr + 1) != '\0') {
 
283
                if (strl2llrc(ptr + 1, strlen(ptr + 1), &pattern->val.range.max) != 0)
 
284
                        goto not_valid_range;
 
285
 
 
286
                pattern->val.range.min_set = 0;
 
287
                pattern->val.range.max_set = 1;
 
288
                return 1;
 
289
        }
 
290
 
 
291
        /* If separator is the last character. */
 
292
        if (*(ptr + 1) == '\0') {
 
293
                if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0)
 
294
                        goto not_valid_range;
 
295
 
 
296
                pattern->val.range.min_set = 1;
 
297
                pattern->val.range.max_set = 0;
 
298
                return 1;
 
299
        }
 
300
 
 
301
        /* Else, parse two numbers. */
 
302
        if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0)
 
303
                goto not_valid_range;
 
304
 
 
305
        if (strl2llrc(ptr + 1, strlen(ptr + 1), &pattern->val.range.max) != 0)
 
306
                goto not_valid_range;
 
307
 
 
308
        if (pattern->val.range.min > pattern->val.range.max)
 
309
                goto not_valid_range;
 
310
 
 
311
        pattern->val.range.min_set = 1;
 
312
        pattern->val.range.max_set = 1;
 
313
        return 1;
 
314
 
 
315
 not_valid_range:
 
316
        memprintf(err, "'%s' is not a valid number range", text);
 
317
        return 0;
 
318
}
 
319
 
 
320
/* Parse a range of positive 2-component versions delimited by either ':' or
 
321
 * '-'. The version consists in a major and a minor, both of which must be
 
322
 * smaller than 65536, because internally they will be represented as a 32-bit
 
323
 * integer.
 
324
 * If only one version is read, it is set as both min and max. Just like for
 
325
 * pure integers, an operator may be specified as the prefix, among this list
 
326
 * of 5 :
 
327
 *
 
328
 *    0:eq, 1:gt, 2:ge, 3:lt, 4:le
 
329
 *
 
330
 * The default operator is "eq". It supports range matching. Ranges are
 
331
 * rejected for other operators. The operator may be changed at any time.
 
332
 * The operator is stored in the 'opaque' argument. This allows constructs
 
333
 * such as the following one :
 
334
 *
 
335
 *    acl obsolete_ssl    ssl_req_proto lt 3
 
336
 *    acl unsupported_ssl ssl_req_proto gt 3.1
 
337
 *    acl valid_ssl       ssl_req_proto 3.0-3.1
 
338
 *
 
339
 */
 
340
int pat_parse_dotted_ver(const char *text, struct pattern *pattern, int mflags, char **err)
 
341
{
 
342
        const char *ptr = text;
 
343
 
 
344
        pattern->type = SMP_T_UINT;
 
345
 
 
346
        /* Search ':' or '-' separator. */
 
347
        while (*ptr != '\0' && *ptr != ':' && *ptr != '-')
 
348
                ptr++;
 
349
 
 
350
        /* If separator not found. */
 
351
        if (*ptr == '\0' && ptr > text) {
 
352
                if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
 
353
                        memprintf(err, "'%s' is not a dotted number", text);
 
354
                        return 0;
 
355
                }
 
356
                pattern->val.range.max = pattern->val.range.min;
 
357
                pattern->val.range.min_set = 1;
 
358
                pattern->val.range.max_set = 1;
 
359
                return 1;
 
360
        }
 
361
 
 
362
        /* If the separator is the first character. */
 
363
        if (ptr == text && *(ptr+1) != '\0') {
 
364
                if (strl2llrc_dotted(ptr+1, strlen(ptr+1), &pattern->val.range.max) != 0) {
 
365
                        memprintf(err, "'%s' is not a valid dotted number range", text);
 
366
                        return 0;
 
367
                }
 
368
                pattern->val.range.min_set = 0;
 
369
                pattern->val.range.max_set = 1;
 
370
                return 1;
 
371
        }
 
372
 
 
373
        /* If separator is the last character. */
 
374
        if (ptr == &text[strlen(text)-1]) {
 
375
                if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
 
376
                        memprintf(err, "'%s' is not a valid dotted number range", text);
 
377
                        return 0;
 
378
                }
 
379
                pattern->val.range.min_set = 1;
 
380
                pattern->val.range.max_set = 0;
 
381
                return 1;
 
382
        }
 
383
 
 
384
        /* Else, parse two numbers. */
 
385
        if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
 
386
                memprintf(err, "'%s' is not a valid dotted number range", text);
 
387
                return 0;
 
388
        }
 
389
        if (strl2llrc_dotted(ptr+1, strlen(ptr+1), &pattern->val.range.max) != 0) {
 
390
                memprintf(err, "'%s' is not a valid dotted number range", text);
 
391
                return 0;
 
392
        }
 
393
        if (pattern->val.range.min > pattern->val.range.max) {
 
394
                memprintf(err, "'%s' is not a valid dotted number range", text);
 
395
                return 0;
 
396
        }
 
397
        pattern->val.range.min_set = 1;
 
398
        pattern->val.range.max_set = 1;
 
399
        return 1;
 
400
}
 
401
 
 
402
/* Parse an IP address and an optional mask in the form addr[/mask].
 
403
 * The addr may either be an IPv4 address or a hostname. The mask
 
404
 * may either be a dotted mask or a number of bits. Returns 1 if OK,
 
405
 * otherwise 0. NOTE: IP address patterns are typed (IPV4/IPV6).
 
406
 */
 
407
int pat_parse_ip(const char *text, struct pattern *pattern, int mflags, char **err)
 
408
{
 
409
        if (str2net(text, !(mflags & PAT_MF_NO_DNS) && (global.mode & MODE_STARTING),
 
410
                    &pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) {
 
411
                pattern->type = SMP_T_IPV4;
 
412
                return 1;
 
413
        }
 
414
        else if (str62net(text, &pattern->val.ipv6.addr, &pattern->val.ipv6.mask)) {
 
415
                pattern->type = SMP_T_IPV6;
 
416
                return 1;
 
417
        }
 
418
        else {
 
419
                memprintf(err, "'%s' is not a valid IPv4 or IPv6 address", text);
 
420
                return 0;
 
421
        }
 
422
}
 
423
 
 
424
/*
 
425
 *
 
426
 * These functions are exported and may be used by any other component.
 
427
 *
 
428
 * This fucntion just take a sample <smp> and check if this sample match
 
429
 * with the pattern <pattern>. This fucntion return just PAT_MATCH or
 
430
 * PAT_NOMATCH.
 
431
 *
 
432
 */
 
433
 
 
434
/* always return false */
 
435
struct pattern *pat_match_nothing(struct sample *smp, struct pattern_expr *expr, int fill)
 
436
{
 
437
        if (smp->data.uint) {
 
438
                if (fill) {
 
439
                        static_pattern.smp = NULL;
 
440
                        static_pattern.ref = NULL;
 
441
                        static_pattern.type = 0;
 
442
                        static_pattern.ptr.str = NULL;
 
443
                }
 
444
                return &static_pattern;
 
445
        }
 
446
        else
 
447
                return NULL;
 
448
}
 
449
 
 
450
 
 
451
/* NB: For two strings to be identical, it is required that their lengths match */
 
452
struct pattern *pat_match_str(struct sample *smp, struct pattern_expr *expr, int fill)
 
453
{
 
454
        int icase;
 
455
        struct ebmb_node *node;
 
456
        char prev;
 
457
        struct pattern_tree *elt;
 
458
        struct pattern_list *lst;
 
459
        struct pattern *pattern;
 
460
 
 
461
        /* Lookup a string in the expression's pattern tree. */
 
462
        if (!eb_is_empty(&expr->pattern_tree)) {
 
463
                /* we may have to force a trailing zero on the test pattern */
 
464
                prev = smp->data.str.str[smp->data.str.len];
 
465
                if (prev)
 
466
                        smp->data.str.str[smp->data.str.len] = '\0';
 
467
                node = ebst_lookup(&expr->pattern_tree, smp->data.str.str);
 
468
                if (prev)
 
469
                        smp->data.str.str[smp->data.str.len] = prev;
 
470
 
 
471
                if (node) {
 
472
                        if (fill) {
 
473
                                elt = ebmb_entry(node, struct pattern_tree, node);
 
474
                                static_pattern.smp = elt->smp;
 
475
                                static_pattern.ref = elt->ref;
 
476
                                static_pattern.sflags = PAT_SF_TREE;
 
477
                                static_pattern.type = SMP_T_STR;
 
478
                                static_pattern.ptr.str = (char *)elt->node.key;
 
479
                        }
 
480
                        return &static_pattern;
 
481
                }
 
482
        }
 
483
 
 
484
        /* look in the list */
 
485
        list_for_each_entry(lst, &expr->patterns, list) {
 
486
                pattern = &lst->pat;
 
487
 
 
488
                if (pattern->len != smp->data.str.len)
 
489
                        continue;
 
490
 
 
491
                icase = expr->mflags & PAT_MF_IGNORE_CASE;
 
492
                if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0) ||
 
493
                    (!icase && strncmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0))
 
494
                        return pattern;
 
495
        }
 
496
 
 
497
        return NULL;
 
498
}
 
499
 
 
500
/* NB: For two binaries buf to be identical, it is required that their lengths match */
 
501
struct pattern *pat_match_bin(struct sample *smp, struct pattern_expr *expr, int fill)
 
502
{
 
503
        struct pattern_list *lst;
 
504
        struct pattern *pattern;
 
505
 
 
506
        /* Look in the list. */
 
507
        list_for_each_entry(lst, &expr->patterns, list) {
 
508
                pattern = &lst->pat;
 
509
 
 
510
                if (pattern->len != smp->data.str.len)
 
511
                        continue;
 
512
 
 
513
                if (memcmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0)
 
514
                        return pattern;
 
515
        }
 
516
 
 
517
        return NULL;
 
518
}
 
519
 
 
520
/* Executes a regex. It temporarily changes the data to add a trailing zero,
 
521
 * and restores the previous character when leaving.
 
522
 */
 
523
struct pattern *pat_match_reg(struct sample *smp, struct pattern_expr *expr, int fill)
 
524
{
 
525
        struct pattern_list *lst;
 
526
        struct pattern *pattern;
 
527
 
 
528
        /* look in the list */
 
529
        list_for_each_entry(lst, &expr->patterns, list) {
 
530
                pattern = &lst->pat;
 
531
 
 
532
                if (regex_exec2(pattern->ptr.reg, smp->data.str.str, smp->data.str.len))
 
533
                        return pattern;
 
534
        }
 
535
        return NULL;
 
536
}
 
537
 
 
538
/* Checks that the pattern matches the beginning of the tested string. */
 
539
struct pattern *pat_match_beg(struct sample *smp, struct pattern_expr *expr, int fill)
 
540
{
 
541
        int icase;
 
542
        struct ebmb_node *node;
 
543
        char prev;
 
544
        struct pattern_tree *elt;
 
545
        struct pattern_list *lst;
 
546
        struct pattern *pattern;
 
547
 
 
548
        /* Lookup a string in the expression's pattern tree. */
 
549
        if (!eb_is_empty(&expr->pattern_tree)) {
 
550
                /* we may have to force a trailing zero on the test pattern */
 
551
                prev = smp->data.str.str[smp->data.str.len];
 
552
                if (prev)
 
553
                        smp->data.str.str[smp->data.str.len] = '\0';
 
554
                node = ebmb_lookup_longest(&expr->pattern_tree, smp->data.str.str);
 
555
                if (prev)
 
556
                        smp->data.str.str[smp->data.str.len] = prev;
 
557
 
 
558
                if (node) {
 
559
                        if (fill) {
 
560
                                elt = ebmb_entry(node, struct pattern_tree, node);
 
561
                                static_pattern.smp = elt->smp;
 
562
                                static_pattern.ref = elt->ref;
 
563
                                static_pattern.sflags = PAT_SF_TREE;
 
564
                                static_pattern.type = SMP_T_STR;
 
565
                                static_pattern.ptr.str = (char *)elt->node.key;
 
566
                        }
 
567
                        return &static_pattern;
 
568
                }
 
569
        }
 
570
 
 
571
        /* look in the list */
 
572
        list_for_each_entry(lst, &expr->patterns, list) {
 
573
                pattern = &lst->pat;
 
574
 
 
575
                if (pattern->len > smp->data.str.len)
 
576
                        continue;
 
577
 
 
578
                icase = expr->mflags & PAT_MF_IGNORE_CASE;
 
579
                if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str, pattern->len) != 0) ||
 
580
                    (!icase && strncmp(pattern->ptr.str, smp->data.str.str, pattern->len) != 0))
 
581
                        continue;
 
582
 
 
583
                return pattern;
 
584
        }
 
585
        return NULL;
 
586
}
 
587
 
 
588
/* Checks that the pattern matches the end of the tested string. */
 
589
struct pattern *pat_match_end(struct sample *smp, struct pattern_expr *expr, int fill)
 
590
{
 
591
        int icase;
 
592
        struct pattern_list *lst;
 
593
        struct pattern *pattern;
 
594
 
 
595
        list_for_each_entry(lst, &expr->patterns, list) {
 
596
                pattern = &lst->pat;
 
597
 
 
598
                if (pattern->len > smp->data.str.len)
 
599
                        continue;
 
600
 
 
601
                icase = expr->mflags & PAT_MF_IGNORE_CASE;
 
602
                if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str + smp->data.str.len - pattern->len, pattern->len) != 0) ||
 
603
                    (!icase && strncmp(pattern->ptr.str, smp->data.str.str + smp->data.str.len - pattern->len, pattern->len) != 0))
 
604
                        continue;
 
605
 
 
606
                return pattern;
 
607
        }
 
608
        return  NULL;
 
609
}
 
610
 
 
611
/* Checks that the pattern is included inside the tested string.
 
612
 * NB: Suboptimal, should be rewritten using a Boyer-Moore method.
 
613
 */
 
614
struct pattern *pat_match_sub(struct sample *smp, struct pattern_expr *expr, int fill)
 
615
{
 
616
        int icase;
 
617
        char *end;
 
618
        char *c;
 
619
        struct pattern_list *lst;
 
620
        struct pattern *pattern;
 
621
 
 
622
        list_for_each_entry(lst, &expr->patterns, list) {
 
623
                pattern = &lst->pat;
 
624
 
 
625
                if (pattern->len > smp->data.str.len)
 
626
                        continue;
 
627
 
 
628
                end = smp->data.str.str + smp->data.str.len - pattern->len;
 
629
                icase = expr->mflags & PAT_MF_IGNORE_CASE;
 
630
                if (icase) {
 
631
                        for (c = smp->data.str.str; c <= end; c++) {
 
632
                                if (tolower(*c) != tolower(*pattern->ptr.str))
 
633
                                        continue;
 
634
                                if (strncasecmp(pattern->ptr.str, c, pattern->len) == 0)
 
635
                                        return pattern;
 
636
                        }
 
637
                } else {
 
638
                        for (c = smp->data.str.str; c <= end; c++) {
 
639
                                if (*c != *pattern->ptr.str)
 
640
                                        continue;
 
641
                                if (strncmp(pattern->ptr.str, c, pattern->len) == 0)
 
642
                                        return pattern;
 
643
                        }
 
644
                }
 
645
        }
 
646
        return NULL;
 
647
}
 
648
 
 
649
/* This one is used by other real functions. It checks that the pattern is
 
650
 * included inside the tested string, but enclosed between the specified
 
651
 * delimiters or at the beginning or end of the string. The delimiters are
 
652
 * provided as an unsigned int made by make_4delim() and match up to 4 different
 
653
 * delimiters. Delimiters are stripped at the beginning and end of the pattern.
 
654
 */
 
655
static int match_word(struct sample *smp, struct pattern *pattern, int mflags, unsigned int delimiters)
 
656
{
 
657
        int may_match, icase;
 
658
        char *c, *end;
 
659
        char *ps;
 
660
        int pl;
 
661
 
 
662
        pl = pattern->len;
 
663
        ps = pattern->ptr.str;
 
664
 
 
665
        while (pl > 0 && is_delimiter(*ps, delimiters)) {
 
666
                pl--;
 
667
                ps++;
 
668
        }
 
669
 
 
670
        while (pl > 0 && is_delimiter(ps[pl - 1], delimiters))
 
671
                pl--;
 
672
 
 
673
        if (pl > smp->data.str.len)
 
674
                return PAT_NOMATCH;
 
675
 
 
676
        may_match = 1;
 
677
        icase = mflags & PAT_MF_IGNORE_CASE;
 
678
        end = smp->data.str.str + smp->data.str.len - pl;
 
679
        for (c = smp->data.str.str; c <= end; c++) {
 
680
                if (is_delimiter(*c, delimiters)) {
 
681
                        may_match = 1;
 
682
                        continue;
 
683
                }
 
684
 
 
685
                if (!may_match)
 
686
                        continue;
 
687
 
 
688
                if (icase) {
 
689
                        if ((tolower(*c) == tolower(*ps)) &&
 
690
                            (strncasecmp(ps, c, pl) == 0) &&
 
691
                            (c == end || is_delimiter(c[pl], delimiters)))
 
692
                                return PAT_MATCH;
 
693
                } else {
 
694
                        if ((*c == *ps) &&
 
695
                            (strncmp(ps, c, pl) == 0) &&
 
696
                            (c == end || is_delimiter(c[pl], delimiters)))
 
697
                                return PAT_MATCH;
 
698
                }
 
699
                may_match = 0;
 
700
        }
 
701
        return PAT_NOMATCH;
 
702
}
 
703
 
 
704
/* Checks that the pattern is included inside the tested string, but enclosed
 
705
 * between the delimiters '?' or '/' or at the beginning or end of the string.
 
706
 * Delimiters at the beginning or end of the pattern are ignored.
 
707
 */
 
708
struct pattern *pat_match_dir(struct sample *smp, struct pattern_expr *expr, int fill)
 
709
{
 
710
        struct pattern_list *lst;
 
711
        struct pattern *pattern;
 
712
 
 
713
        list_for_each_entry(lst, &expr->patterns, list) {
 
714
                pattern = &lst->pat;
 
715
                if (match_word(smp, pattern, expr->mflags, make_4delim('/', '?', '?', '?')))
 
716
                        return pattern;
 
717
        }
 
718
        return NULL;
 
719
}
 
720
 
 
721
/* Checks that the pattern is included inside the tested string, but enclosed
 
722
 * between the delmiters '/', '?', '.' or ":" or at the beginning or end of
 
723
 * the string. Delimiters at the beginning or end of the pattern are ignored.
 
724
 */
 
725
struct pattern *pat_match_dom(struct sample *smp, struct pattern_expr *expr, int fill)
 
726
{
 
727
        struct pattern_list *lst;
 
728
        struct pattern *pattern;
 
729
 
 
730
        list_for_each_entry(lst, &expr->patterns, list) {
 
731
                pattern = &lst->pat;
 
732
                if (match_word(smp, pattern, expr->mflags, make_4delim('/', '?', '.', ':')))
 
733
                        return pattern;
 
734
        }
 
735
        return NULL;
 
736
}
 
737
 
 
738
/* Checks that the integer in <test> is included between min and max */
 
739
struct pattern *pat_match_int(struct sample *smp, struct pattern_expr *expr, int fill)
 
740
{
 
741
        struct pattern_list *lst;
 
742
        struct pattern *pattern;
 
743
 
 
744
        list_for_each_entry(lst, &expr->patterns, list) {
 
745
                pattern = &lst->pat;
 
746
                if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.uint) &&
 
747
                    (!pattern->val.range.max_set || smp->data.uint <= pattern->val.range.max))
 
748
                        return pattern;
 
749
        }
 
750
        return NULL;
 
751
}
 
752
 
 
753
/* Checks that the length of the pattern in <test> is included between min and max */
 
754
struct pattern *pat_match_len(struct sample *smp, struct pattern_expr *expr, int fill)
 
755
{
 
756
        struct pattern_list *lst;
 
757
        struct pattern *pattern;
 
758
 
 
759
        list_for_each_entry(lst, &expr->patterns, list) {
 
760
                pattern = &lst->pat;
 
761
                if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.str.len) &&
 
762
                    (!pattern->val.range.max_set || smp->data.str.len <= pattern->val.range.max))
 
763
                        return pattern;
 
764
        }
 
765
        return NULL;
 
766
}
 
767
 
 
768
struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int fill)
 
769
{
 
770
        unsigned int v4; /* in network byte order */
 
771
        struct in6_addr tmp6;
 
772
        struct in_addr *s;
 
773
        struct ebmb_node *node;
 
774
        struct pattern_tree *elt;
 
775
        struct pattern_list *lst;
 
776
        struct pattern *pattern;
 
777
 
 
778
        /* The input sample is IPv4. Try to match in the trees. */
 
779
        if (smp->type == SMP_T_IPV4) {
 
780
                /* Lookup an IPv4 address in the expression's pattern tree using
 
781
                 * the longest match method.
 
782
                 */
 
783
                s = &smp->data.ipv4;
 
784
                node = ebmb_lookup_longest(&expr->pattern_tree, &s->s_addr);
 
785
                if (node) {
 
786
                        if (fill) {
 
787
                                elt = ebmb_entry(node, struct pattern_tree, node);
 
788
                                static_pattern.smp = elt->smp;
 
789
                                static_pattern.ref = elt->ref;
 
790
                                static_pattern.sflags = PAT_SF_TREE;
 
791
                                static_pattern.type = SMP_T_IPV4;
 
792
                                memcpy(&static_pattern.val.ipv4.addr.s_addr, elt->node.key, 4);
 
793
                                if (!cidr2dotted(elt->node.node.pfx, &static_pattern.val.ipv4.mask))
 
794
                                        return NULL;
 
795
                        }
 
796
                        return &static_pattern;
 
797
                }
 
798
 
 
799
                /* The IPv4 sample dont match the IPv4 tree. Convert the IPv4
 
800
                 * sample address to IPv6 with the mapping method using the ::ffff:
 
801
                 * prefix, and try to lookup in the IPv6 tree.
 
802
                 */
 
803
                memset(&tmp6, 0, 10);
 
804
                *(uint16_t*)&tmp6.s6_addr[10] = htons(0xffff);
 
805
                *(uint32_t*)&tmp6.s6_addr[12] = smp->data.ipv4.s_addr;
 
806
                node = ebmb_lookup_longest(&expr->pattern_tree_2, &tmp6);
 
807
                if (node) {
 
808
                        if (fill) {
 
809
                                elt = ebmb_entry(node, struct pattern_tree, node);
 
810
                                static_pattern.smp = elt->smp;
 
811
                                static_pattern.ref = elt->ref;
 
812
                                static_pattern.sflags = PAT_SF_TREE;
 
813
                                static_pattern.type = SMP_T_IPV6;
 
814
                                memcpy(&static_pattern.val.ipv6.addr, elt->node.key, 16);
 
815
                                static_pattern.val.ipv6.mask = elt->node.node.pfx;
 
816
                        }
 
817
                        return &static_pattern;
 
818
                }
 
819
        }
 
820
 
 
821
        /* The input sample is IPv6. Try to match in the trees. */
 
822
        if (smp->type == SMP_T_IPV6) {
 
823
                /* Lookup an IPv6 address in the expression's pattern tree using
 
824
                 * the longest match method.
 
825
                 */
 
826
                node = ebmb_lookup_longest(&expr->pattern_tree_2, &smp->data.ipv6);
 
827
                if (node) {
 
828
                        if (fill) {
 
829
                                elt = ebmb_entry(node, struct pattern_tree, node);
 
830
                                static_pattern.smp = elt->smp;
 
831
                                static_pattern.ref = elt->ref;
 
832
                                static_pattern.sflags = PAT_SF_TREE;
 
833
                                static_pattern.type = SMP_T_IPV6;
 
834
                                memcpy(&static_pattern.val.ipv6.addr, elt->node.key, 16);
 
835
                                static_pattern.val.ipv6.mask = elt->node.node.pfx;
 
836
                        }
 
837
                        return &static_pattern;
 
838
                }
 
839
 
 
840
                /* Try to convert 6 to 4 when the start of the ipv6 address match the
 
841
                 * following forms :
 
842
                 *   - ::ffff:ip:v4 (ipv4 mapped)
 
843
                 *   - ::0000:ip:v4 (old ipv4 mapped)
 
844
                 *   - 2002:ip:v4:: (6to4)
 
845
                 */
 
846
                if ((*(uint32_t*)&smp->data.ipv6.s6_addr[0] == 0 &&
 
847
                     *(uint32_t*)&smp->data.ipv6.s6_addr[4]  == 0 &&
 
848
                     (*(uint32_t*)&smp->data.ipv6.s6_addr[8] == 0 ||
 
849
                      *(uint32_t*)&smp->data.ipv6.s6_addr[8] == htonl(0xFFFF))) ||
 
850
                    *(uint16_t*)&smp->data.ipv6.s6_addr[0] == htons(0x2002)) {
 
851
                        if (*(uint32_t*)&smp->data.ipv6.s6_addr[0] == 0)
 
852
                                v4 = *(uint32_t*)&smp->data.ipv6.s6_addr[12];
 
853
                        else
 
854
                                v4 = htonl((ntohs(*(uint16_t*)&smp->data.ipv6.s6_addr[2]) << 16) +
 
855
                                            ntohs(*(uint16_t*)&smp->data.ipv6.s6_addr[4]));
 
856
 
 
857
                        /* Lookup an IPv4 address in the expression's pattern tree using the longest
 
858
                         * match method.
 
859
                         */
 
860
                        node = ebmb_lookup_longest(&expr->pattern_tree, &v4);
 
861
                        if (node) {
 
862
                                if (fill) {
 
863
                                        elt = ebmb_entry(node, struct pattern_tree, node);
 
864
                                        static_pattern.smp = elt->smp;
 
865
                                        static_pattern.ref = elt->ref;
 
866
                                        static_pattern.sflags = PAT_SF_TREE;
 
867
                                        static_pattern.type = SMP_T_IPV4;
 
868
                                        memcpy(&static_pattern.val.ipv4.addr.s_addr, elt->node.key, 4);
 
869
                                        if (!cidr2dotted(elt->node.node.pfx, &static_pattern.val.ipv4.mask))
 
870
                                                return NULL;
 
871
                                }
 
872
                                return &static_pattern;
 
873
                        }
 
874
                }
 
875
        }
 
876
 
 
877
        /* Lookup in the list. the list contain only IPv4 patterns */
 
878
        list_for_each_entry(lst, &expr->patterns, list) {
 
879
                pattern = &lst->pat;
 
880
 
 
881
                /* The input sample is IPv4, use it as is. */
 
882
                if (smp->type == SMP_T_IPV4) {
 
883
                        v4 = smp->data.ipv4.s_addr;
 
884
                }
 
885
                else if (smp->type == SMP_T_IPV6) {
 
886
                        /* v4 match on a V6 sample. We want to check at least for
 
887
                         * the following forms :
 
888
                         *   - ::ffff:ip:v4 (ipv4 mapped)
 
889
                         *   - ::0000:ip:v4 (old ipv4 mapped)
 
890
                         *   - 2002:ip:v4:: (6to4)
 
891
                         */
 
892
                        if (*(uint32_t*)&smp->data.ipv6.s6_addr[0] == 0 &&
 
893
                            *(uint32_t*)&smp->data.ipv6.s6_addr[4]  == 0 &&
 
894
                            (*(uint32_t*)&smp->data.ipv6.s6_addr[8] == 0 ||
 
895
                             *(uint32_t*)&smp->data.ipv6.s6_addr[8] == htonl(0xFFFF))) {
 
896
                                v4 = *(uint32_t*)&smp->data.ipv6.s6_addr[12];
 
897
                        }
 
898
                        else if (*(uint16_t*)&smp->data.ipv6.s6_addr[0] == htons(0x2002)) {
 
899
                                v4 = htonl((ntohs(*(uint16_t*)&smp->data.ipv6.s6_addr[2]) << 16) +
 
900
                                            ntohs(*(uint16_t*)&smp->data.ipv6.s6_addr[4]));
 
901
                        }
 
902
                        else
 
903
                                continue;
 
904
                }
 
905
 
 
906
                /* Check if the input sample match the current pattern. */
 
907
                if (((v4 ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0)
 
908
                        return pattern;
 
909
        }
 
910
        return NULL;
 
911
}
 
912
 
 
913
void free_pattern_tree(struct eb_root *root)
 
914
{
 
915
        struct eb_node *node, *next;
 
916
        struct pattern_tree *elt;
 
917
 
 
918
        node = eb_first(root);
 
919
        while (node) {
 
920
                next = eb_next(node);
 
921
                eb_delete(node);
 
922
                elt = container_of(node, struct pattern_tree, node);
 
923
                free(elt->smp);
 
924
                free(elt);
 
925
                node = next;
 
926
        }
 
927
}
 
928
 
 
929
void pat_prune_val(struct pattern_expr *expr)
 
930
{
 
931
        struct pattern_list *pat, *tmp;
 
932
 
 
933
        list_for_each_entry_safe(pat, tmp, &expr->patterns, list) {
 
934
                free(pat->pat.smp);
 
935
                free(pat);
 
936
        }
 
937
 
 
938
        free_pattern_tree(&expr->pattern_tree);
 
939
        free_pattern_tree(&expr->pattern_tree_2);
 
940
        LIST_INIT(&expr->patterns);
 
941
}
 
942
 
 
943
void pat_prune_ptr(struct pattern_expr *expr)
 
944
{
 
945
        struct pattern_list *pat, *tmp;
 
946
 
 
947
        list_for_each_entry_safe(pat, tmp, &expr->patterns, list) {
 
948
                free(pat->pat.ptr.ptr);
 
949
                free(pat->pat.smp);
 
950
                free(pat);
 
951
        }
 
952
 
 
953
        free_pattern_tree(&expr->pattern_tree);
 
954
        free_pattern_tree(&expr->pattern_tree_2);
 
955
        LIST_INIT(&expr->patterns);
 
956
}
 
957
 
 
958
void pat_prune_reg(struct pattern_expr *expr)
 
959
{
 
960
        struct pattern_list *pat, *tmp;
 
961
 
 
962
        list_for_each_entry_safe(pat, tmp, &expr->patterns, list) {
 
963
                regex_free(pat->pat.ptr.ptr);
 
964
                free(pat->pat.smp);
 
965
                free(pat);
 
966
        }
 
967
 
 
968
        free_pattern_tree(&expr->pattern_tree);
 
969
        free_pattern_tree(&expr->pattern_tree_2);
 
970
        LIST_INIT(&expr->patterns);
 
971
}
 
972
 
 
973
/*
 
974
 *
 
975
 * The following functions are used for the pattern indexation
 
976
 *
 
977
 */
 
978
 
 
979
int pat_idx_list_val(struct pattern_expr *expr, struct pattern *pat, char **err)
 
980
{
 
981
        struct pattern_list *patl;
 
982
 
 
983
        /* allocate pattern */
 
984
        patl = calloc(1, sizeof(*patl));
 
985
        if (!patl) {
 
986
                memprintf(err, "out of memory while indexing pattern");
 
987
                return 0;
 
988
        }
 
989
 
 
990
        /* duplicate pattern */
 
991
        memcpy(&patl->pat, pat, sizeof(*pat));
 
992
 
 
993
        /* chain pattern in the expression */
 
994
        LIST_ADDQ(&expr->patterns, &patl->list);
 
995
 
 
996
        /* that's ok */
 
997
        return 1;
 
998
}
 
999
 
 
1000
int pat_idx_list_ptr(struct pattern_expr *expr, struct pattern *pat, char **err)
 
1001
{
 
1002
        struct pattern_list *patl;
 
1003
 
 
1004
        /* allocate pattern */
 
1005
        patl = calloc(1, sizeof(*patl));
 
1006
        if (!patl)
 
1007
                return 0;
 
1008
 
 
1009
        /* duplicate pattern */
 
1010
        memcpy(&patl->pat, pat, sizeof(*pat));
 
1011
        patl->pat.ptr.ptr = malloc(patl->pat.len);
 
1012
        if (!patl->pat.ptr.ptr) {
 
1013
                free(patl);
 
1014
                memprintf(err, "out of memory while indexing pattern");
 
1015
                return 0;
 
1016
        }
 
1017
        memcpy(patl->pat.ptr.ptr, pat->ptr.ptr, pat->len);
 
1018
 
 
1019
        /* chain pattern in the expression */
 
1020
        LIST_ADDQ(&expr->patterns, &patl->list);
 
1021
 
 
1022
        /* that's ok */
 
1023
        return 1;
 
1024
}
 
1025
 
 
1026
int pat_idx_list_str(struct pattern_expr *expr, struct pattern *pat, char **err)
 
1027
{
 
1028
        struct pattern_list *patl;
 
1029
 
 
1030
        /* allocate pattern */
 
1031
        patl = calloc(1, sizeof(*patl));
 
1032
        if (!patl) {
 
1033
                memprintf(err, "out of memory while indexing pattern");
 
1034
                return 0;
 
1035
        }
 
1036
 
 
1037
        /* duplicate pattern */
 
1038
        memcpy(&patl->pat, pat, sizeof(*pat));
 
1039
        patl->pat.ptr.str = malloc(patl->pat.len + 1);
 
1040
        if (!patl->pat.ptr.str) {
 
1041
                free(patl);
 
1042
                memprintf(err, "out of memory while indexing pattern");
 
1043
                return 0;
 
1044
        }
 
1045
        memcpy(patl->pat.ptr.ptr, pat->ptr.ptr, pat->len);
 
1046
        patl->pat.ptr.str[patl->pat.len] = '\0';
 
1047
 
 
1048
        /* chain pattern in the expression */
 
1049
        LIST_ADDQ(&expr->patterns, &patl->list);
 
1050
 
 
1051
        /* that's ok */
 
1052
        return 1;
 
1053
}
 
1054
 
 
1055
int pat_idx_list_reg(struct pattern_expr *expr, struct pattern *pat, char **err)
 
1056
{
 
1057
        struct pattern_list *patl;
 
1058
 
 
1059
        /* allocate pattern */
 
1060
        patl = calloc(1, sizeof(*patl));
 
1061
        if (!patl) {
 
1062
                memprintf(err, "out of memory while indexing pattern");
 
1063
                return 0;
 
1064
        }
 
1065
 
 
1066
        /* duplicate pattern */
 
1067
        memcpy(&patl->pat, pat, sizeof(*pat));
 
1068
 
 
1069
        /* allocate regex */
 
1070
        patl->pat.ptr.reg = calloc(1, sizeof(*patl->pat.ptr.reg));
 
1071
        if (!patl->pat.ptr.reg) {
 
1072
                free(patl);
 
1073
                memprintf(err, "out of memory while indexing pattern");
 
1074
                return 0;
 
1075
        }
 
1076
 
 
1077
        /* compile regex */
 
1078
        if (!regex_comp(pat->ptr.str, patl->pat.ptr.reg, !(expr->mflags & PAT_MF_IGNORE_CASE), 0, err)) {
 
1079
                free(patl->pat.ptr.reg);
 
1080
                free(patl);
 
1081
                return 0;
 
1082
        }
 
1083
 
 
1084
        /* chain pattern in the expression */
 
1085
        LIST_ADDQ(&expr->patterns, &patl->list);
 
1086
 
 
1087
        /* that's ok */
 
1088
        return 1;
 
1089
}
 
1090
 
 
1091
int pat_idx_tree_ip(struct pattern_expr *expr, struct pattern *pat, char **err)
 
1092
{
 
1093
        unsigned int mask;
 
1094
        struct pattern_tree *node;
 
1095
 
 
1096
        /* Only IPv4 can be indexed */
 
1097
        if (pat->type == SMP_T_IPV4) {
 
1098
                /* in IPv4 case, check if the mask is contiguous so that we can
 
1099
                 * insert the network into the tree. A continuous mask has only
 
1100
                 * ones on the left. This means that this mask + its lower bit
 
1101
                 * added once again is null.
 
1102
                 */
 
1103
                mask = ntohl(pat->val.ipv4.mask.s_addr);
 
1104
                if (mask + (mask & -mask) == 0) {
 
1105
                        mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
 
1106
 
 
1107
                        /* node memory allocation */
 
1108
                        node = calloc(1, sizeof(*node) + 4);
 
1109
                        if (!node) {
 
1110
                                memprintf(err, "out of memory while loading pattern");
 
1111
                                return 0;
 
1112
                        }
 
1113
 
 
1114
                        /* copy the pointer to sample associated to this node */
 
1115
                        node->smp = pat->smp;
 
1116
                        node->ref = pat->ref;
 
1117
 
 
1118
                        /* FIXME: insert <addr>/<mask> into the tree here */
 
1119
                        memcpy(node->node.key, &pat->val.ipv4.addr, 4); /* network byte order */
 
1120
                        node->node.node.pfx = mask;
 
1121
 
 
1122
                        /* Insert the entry. */
 
1123
                        ebmb_insert_prefix(&expr->pattern_tree, &node->node, 4);
 
1124
 
 
1125
                        /* that's ok */
 
1126
                        return 1;
 
1127
                }
 
1128
                else {
 
1129
                        /* If the mask is not contiguous, just add the pattern to the list */
 
1130
                        return pat_idx_list_val(expr, pat, err);
 
1131
                }
 
1132
        }
 
1133
        else if (pat->type == SMP_T_IPV6) {
 
1134
                /* IPv6 also can be indexed */
 
1135
                node = calloc(1, sizeof(*node) + 16);
 
1136
                if (!node) {
 
1137
                        memprintf(err, "out of memory while loading pattern");
 
1138
                        return 0;
 
1139
                }
 
1140
 
 
1141
                /* copy the pointer to sample associated to this node */
 
1142
                node->smp = pat->smp;
 
1143
                node->ref = pat->ref;
 
1144
 
 
1145
                /* FIXME: insert <addr>/<mask> into the tree here */
 
1146
                memcpy(node->node.key, &pat->val.ipv6.addr, 16); /* network byte order */
 
1147
                node->node.node.pfx = pat->val.ipv6.mask;
 
1148
 
 
1149
                /* Insert the entry. */
 
1150
                ebmb_insert_prefix(&expr->pattern_tree_2, &node->node, 16);
 
1151
 
 
1152
                /* that's ok */
 
1153
                return 1;
 
1154
        }
 
1155
 
 
1156
        return 0;
 
1157
}
 
1158
 
 
1159
int pat_idx_tree_str(struct pattern_expr *expr, struct pattern *pat, char **err)
 
1160
{
 
1161
        int len;
 
1162
        struct pattern_tree *node;
 
1163
 
 
1164
        /* Only string can be indexed */
 
1165
        if (pat->type != SMP_T_STR) {
 
1166
                memprintf(err, "internal error: string expected, but the type is '%s'",
 
1167
                          smp_to_type[pat->type]);
 
1168
                return 0;
 
1169
        }
 
1170
 
 
1171
        /* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
 
1172
        if (expr->mflags & PAT_MF_IGNORE_CASE)
 
1173
                return pat_idx_list_str(expr, pat, err);
 
1174
 
 
1175
        /* Process the key len */
 
1176
        len = strlen(pat->ptr.str) + 1;
 
1177
 
 
1178
        /* node memory allocation */
 
1179
        node = calloc(1, sizeof(*node) + len);
 
1180
        if (!node) {
 
1181
                memprintf(err, "out of memory while loading pattern");
 
1182
                return 0;
 
1183
        }
 
1184
 
 
1185
        /* copy the pointer to sample associated to this node */
 
1186
        node->smp = pat->smp;
 
1187
        node->ref = pat->ref;
 
1188
 
 
1189
        /* copy the string */
 
1190
        memcpy(node->node.key, pat->ptr.str, len);
 
1191
 
 
1192
        /* index the new node */
 
1193
        ebst_insert(&expr->pattern_tree, &node->node);
 
1194
 
 
1195
        /* that's ok */
 
1196
        return 1;
 
1197
}
 
1198
 
 
1199
int pat_idx_tree_pfx(struct pattern_expr *expr, struct pattern *pat, char **err)
 
1200
{
 
1201
        int len;
 
1202
        struct pattern_tree *node;
 
1203
 
 
1204
        /* Only string can be indexed */
 
1205
        if (pat->type != SMP_T_STR) {
 
1206
                memprintf(err, "internal error: string expected, but the type is '%s'",
 
1207
                          smp_to_type[pat->type]);
 
1208
                return 0;
 
1209
        }
 
1210
 
 
1211
        /* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
 
1212
        if (expr->mflags & PAT_MF_IGNORE_CASE)
 
1213
                return pat_idx_list_str(expr, pat, err);
 
1214
 
 
1215
        /* Process the key len */
 
1216
        len = strlen(pat->ptr.str);
 
1217
 
 
1218
        /* node memory allocation */
 
1219
        node = calloc(1, sizeof(*node) + len + 1);
 
1220
        if (!node) {
 
1221
                memprintf(err, "out of memory while loading pattern");
 
1222
                return 0;
 
1223
        }
 
1224
 
 
1225
        /* copy the pointer to sample associated to this node */
 
1226
        node->smp = pat->smp;
 
1227
        node->ref = pat->ref;
 
1228
 
 
1229
        /* copy the string and the trailing zero */
 
1230
        memcpy(node->node.key, pat->ptr.str, len + 1);
 
1231
        node->node.node.pfx = len * 8;
 
1232
 
 
1233
        /* index the new node */
 
1234
        ebmb_insert_prefix(&expr->pattern_tree, &node->node, len);
 
1235
 
 
1236
        /* that's ok */
 
1237
        return 1;
 
1238
}
 
1239
 
 
1240
void pat_del_list_val(struct pattern_expr *expr, struct pat_ref_elt *ref)
 
1241
{
 
1242
        struct pattern_list *pat;
 
1243
        struct pattern_list *safe;
 
1244
 
 
1245
        list_for_each_entry_safe(pat, safe, &expr->patterns, list) {
 
1246
                /* Check equality. */
 
1247
                if (pat->pat.ref != ref)
 
1248
                        continue;
 
1249
 
 
1250
                /* Delete and free entry. */
 
1251
                LIST_DEL(&pat->list);
 
1252
                free(pat->pat.smp);
 
1253
                free(pat);
 
1254
        }
 
1255
}
 
1256
 
 
1257
void pat_del_tree_ip(struct pattern_expr *expr, struct pat_ref_elt *ref)
 
1258
{
 
1259
        struct ebmb_node *node, *next_node;
 
1260
        struct pattern_tree *elt;
 
1261
 
 
1262
        /* browse each node of the tree for IPv4 addresses. */
 
1263
        for (node = ebmb_first(&expr->pattern_tree), next_node = node ? ebmb_next(node) : NULL;
 
1264
             node;
 
1265
             node = next_node, next_node = node ? ebmb_next(node) : NULL) {
 
1266
                /* Extract container of the tree node. */
 
1267
                elt = container_of(node, struct pattern_tree, node);
 
1268
 
 
1269
                /* Check equality. */
 
1270
                if (elt->ref != ref)
 
1271
                        continue;
 
1272
 
 
1273
                /* Delete and free entry. */
 
1274
                ebmb_delete(node);
 
1275
                free(elt->smp);
 
1276
                free(elt);
 
1277
        }
 
1278
 
 
1279
        /* Browse each node of the list for IPv4 addresses. */
 
1280
        pat_del_list_val(expr, ref);
 
1281
 
 
1282
        /* browse each node of the tree for IPv6 addresses. */
 
1283
        for (node = ebmb_first(&expr->pattern_tree_2), next_node = node ? ebmb_next(node) : NULL;
 
1284
             node;
 
1285
             node = next_node, next_node = node ? ebmb_next(node) : NULL) {
 
1286
                /* Extract container of the tree node. */
 
1287
                elt = container_of(node, struct pattern_tree, node);
 
1288
 
 
1289
                /* Check equality. */
 
1290
                if (elt->ref != ref)
 
1291
                        continue;
 
1292
 
 
1293
                /* Delete and free entry. */
 
1294
                ebmb_delete(node);
 
1295
                free(elt->smp);
 
1296
                free(elt);
 
1297
        }
 
1298
}
 
1299
 
 
1300
void pat_del_list_ptr(struct pattern_expr *expr, struct pat_ref_elt *ref)
 
1301
{
 
1302
        struct pattern_list *pat;
 
1303
        struct pattern_list *safe;
 
1304
 
 
1305
        list_for_each_entry_safe(pat, safe, &expr->patterns, list) {
 
1306
                /* Check equality. */
 
1307
                if (pat->pat.ref != ref)
 
1308
                        continue;
 
1309
 
 
1310
                /* Delete and free entry. */
 
1311
                LIST_DEL(&pat->list);
 
1312
                free(pat->pat.ptr.ptr);
 
1313
                free(pat->pat.smp);
 
1314
                free(pat);
 
1315
        }
 
1316
}
 
1317
 
 
1318
void pat_del_tree_str(struct pattern_expr *expr, struct pat_ref_elt *ref)
 
1319
{
 
1320
        struct ebmb_node *node, *next_node;
 
1321
        struct pattern_tree *elt;
 
1322
 
 
1323
        /* browse each node of the tree. */
 
1324
        for (node = ebmb_first(&expr->pattern_tree), next_node = node ? ebmb_next(node) : NULL;
 
1325
             node;
 
1326
             node = next_node, next_node = node ? ebmb_next(node) : NULL) {
 
1327
                /* Extract container of the tree node. */
 
1328
                elt = container_of(node, struct pattern_tree, node);
 
1329
 
 
1330
                /* Check equality. */
 
1331
                if (elt->ref != ref)
 
1332
                        continue;
 
1333
 
 
1334
                /* Delete and free entry. */
 
1335
                ebmb_delete(node);
 
1336
                free(elt->smp);
 
1337
                free(elt);
 
1338
        }
 
1339
}
 
1340
 
 
1341
void pat_del_list_reg(struct pattern_expr *expr, struct pat_ref_elt *ref)
 
1342
{
 
1343
        struct pattern_list *pat;
 
1344
        struct pattern_list *safe;
 
1345
 
 
1346
        list_for_each_entry_safe(pat, safe, &expr->patterns, list) {
 
1347
                /* Check equality. */
 
1348
                if (pat->pat.ref != ref)
 
1349
                        continue;
 
1350
 
 
1351
                /* Delete and free entry. */
 
1352
                LIST_DEL(&pat->list);
 
1353
                regex_free(pat->pat.ptr.ptr);
 
1354
                free(pat->pat.smp);
 
1355
                free(pat);
 
1356
        }
 
1357
}
 
1358
 
 
1359
void pattern_init_expr(struct pattern_expr *expr)
 
1360
{
 
1361
        LIST_INIT(&expr->patterns);
 
1362
        expr->pattern_tree = EB_ROOT;
 
1363
        expr->pattern_tree_2 = EB_ROOT;
 
1364
}
 
1365
 
 
1366
void pattern_init_head(struct pattern_head *head)
 
1367
{
 
1368
        LIST_INIT(&head->head);
 
1369
}
 
1370
 
 
1371
/* The following functions are relative to the management of the reference
 
1372
 * lists. These lists are used to store the original pattern and associated
 
1373
 * value as string form.
 
1374
 *
 
1375
 * This is used with modifiable ACL and MAPS
 
1376
 *
 
1377
 * The pattern reference are stored with two identifiers: the unique_id and
 
1378
 * the reference.
 
1379
 *
 
1380
 * The reference identify a file. Each file with the same name point to the
 
1381
 * same reference. We can register many times one file. If the file is modified,
 
1382
 * all his dependencies are also modified. The reference can be used with map or
 
1383
 * acl.
 
1384
 *
 
1385
 * The unique_id identify inline acl. The unique id is unique for each acl.
 
1386
 * You cannot force the same id in the configuration file, because this repoort
 
1387
 * an error.
 
1388
 *
 
1389
 * A particular case appears if the filename is a number. In this case, the
 
1390
 * unique_id is set with the number represented by the filename and the
 
1391
 * reference is also set. This method prevent double unique_id.
 
1392
 *
 
1393
 */
 
1394
 
 
1395
/* This function lookup for reference. If the reference is found, they return
 
1396
 * pointer to the struct pat_ref, else return NULL.
 
1397
 */
 
1398
struct pat_ref *pat_ref_lookup(const char *reference)
 
1399
{
 
1400
        struct pat_ref *ref;
 
1401
 
 
1402
        list_for_each_entry(ref, &pattern_reference, list)
 
1403
                if (ref->reference && strcmp(reference, ref->reference) == 0)
 
1404
                        return ref;
 
1405
        return NULL;
 
1406
}
 
1407
 
 
1408
/* This function lookup for unique id. If the reference is found, they return
 
1409
 * pointer to the struct pat_ref, else return NULL.
 
1410
 */
 
1411
struct pat_ref *pat_ref_lookupid(int unique_id)
 
1412
{
 
1413
        struct pat_ref *ref;
 
1414
 
 
1415
        list_for_each_entry(ref, &pattern_reference, list)
 
1416
                if (ref->unique_id == unique_id)
 
1417
                        return ref;
 
1418
        return NULL;
 
1419
}
 
1420
 
 
1421
/* This function remove all pattern matching the pointer <refelt> from
 
1422
 * the the reference and from each expr member of the reference. This
 
1423
 * function returns 1 if the deletion is done and return 0 is the entry
 
1424
 * is not found.
 
1425
 */
 
1426
int pat_ref_delete_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt)
 
1427
{
 
1428
        struct pattern_expr *expr;
 
1429
        struct pat_ref_elt *elt, *safe;
 
1430
 
 
1431
        /* delete pattern from reference */
 
1432
        list_for_each_entry_safe(elt, safe, &ref->head, list) {
 
1433
                if (elt == refelt) {
 
1434
                        LIST_DEL(&elt->list);
 
1435
                        free(elt->sample);
 
1436
                        free(elt->pattern);
 
1437
                        free(elt);
 
1438
 
 
1439
                        list_for_each_entry(expr, &ref->pat, list)
 
1440
                                pattern_delete(expr, elt);
 
1441
 
 
1442
                        return 1;
 
1443
                }
 
1444
        }
 
1445
        return 0;
 
1446
}
 
1447
 
 
1448
/* This function remove all pattern match <key> from the the reference
 
1449
 * and from each expr member of the reference. This fucntion returns 1
 
1450
 * if the deletion is done and return 0 is the entry is not found.
 
1451
 */
 
1452
int pat_ref_delete(struct pat_ref *ref, const char *key)
 
1453
{
 
1454
        struct pattern_expr *expr;
 
1455
        struct pat_ref_elt *elt, *safe;
 
1456
        int found = 0;
 
1457
 
 
1458
        /* delete pattern from reference */
 
1459
        list_for_each_entry_safe(elt, safe, &ref->head, list) {
 
1460
                if (strcmp(key, elt->pattern) == 0) {
 
1461
                        list_for_each_entry(expr, &ref->pat, list)
 
1462
                                pattern_delete(expr, elt);
 
1463
 
 
1464
                        LIST_DEL(&elt->list);
 
1465
                        free(elt->sample);
 
1466
                        free(elt->pattern);
 
1467
                        free(elt);
 
1468
 
 
1469
                        found = 1;
 
1470
                }
 
1471
        }
 
1472
 
 
1473
        if (!found)
 
1474
                return 0;
 
1475
        return 1;
 
1476
}
 
1477
 
 
1478
/*
 
1479
 * find and return an element <elt> matching <key> in a reference <ref>
 
1480
 * return NULL if not found
 
1481
 */
 
1482
struct pat_ref_elt *pat_ref_find_elt(struct pat_ref *ref, const char *key)
 
1483
{
 
1484
        struct pat_ref_elt *elt;
 
1485
 
 
1486
        list_for_each_entry(elt, &ref->head, list) {
 
1487
                if (strcmp(key, elt->pattern) == 0)
 
1488
                        return elt;
 
1489
        }
 
1490
 
 
1491
        return NULL;
 
1492
}
 
1493
 
 
1494
 
 
1495
  /* This function modify the sample of the first pattern that match the <key>. */
 
1496
static inline int pat_ref_set_elt(struct pat_ref *ref, struct pat_ref_elt *elt,
 
1497
                                  const char *value, char **err)
 
1498
{
 
1499
        struct pattern_expr *expr;
 
1500
        struct sample_storage **smp;
 
1501
        char *sample;
 
1502
        struct sample_storage test;
 
1503
 
 
1504
        /* Try all needed converters. */
 
1505
        list_for_each_entry(expr, &ref->pat, list) {
 
1506
                if (!expr->pat_head->parse_smp)
 
1507
                        continue;
 
1508
 
 
1509
                if (!expr->pat_head->parse_smp(value, &test)) {
 
1510
                        memprintf(err, "unable to parse '%s'", value);
 
1511
                        return 0;
 
1512
                }
 
1513
        }
 
1514
 
 
1515
        /* Modify pattern from reference. */
 
1516
        sample = strdup(value);
 
1517
        if (!sample) {
 
1518
                memprintf(err, "out of memory error");
 
1519
                return 0;
 
1520
        }
 
1521
        free(elt->sample);
 
1522
        elt->sample = sample;
 
1523
 
 
1524
        /* Load sample in each reference. All the conversion are tested
 
1525
         * below, normally these calls dosn't fail.
 
1526
         */
 
1527
        list_for_each_entry(expr, &ref->pat, list) {
 
1528
                if (!expr->pat_head->parse_smp)
 
1529
                        continue;
 
1530
 
 
1531
                smp = pattern_find_smp(expr, elt);
 
1532
                if (smp && *smp && !expr->pat_head->parse_smp(sample, *smp))
 
1533
                        *smp = NULL;
 
1534
        }
 
1535
 
 
1536
        return 1;
 
1537
}
 
1538
 
 
1539
/* This function modify the sample of the first pattern that match the <key>. */
 
1540
int pat_ref_set_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt, const char *value, char **err)
 
1541
{
 
1542
        struct pat_ref_elt *elt;
 
1543
 
 
1544
        /* Look for pattern in the reference. */
 
1545
        list_for_each_entry(elt, &ref->head, list) {
 
1546
                if (elt == refelt) {
 
1547
                        if (!pat_ref_set_elt(ref, elt, value, err))
 
1548
                                return 0;
 
1549
                        return 1;
 
1550
                }
 
1551
        }
 
1552
 
 
1553
        memprintf(err, "key or pattern not found");
 
1554
        return 0;
 
1555
}
 
1556
 
 
1557
/* This function modify the sample of the first pattern that match the <key>. */
 
1558
int pat_ref_set(struct pat_ref *ref, const char *key, const char *value, char **err)
 
1559
{
 
1560
        struct pat_ref_elt *elt;
 
1561
        int found = 0;
 
1562
        char *_merr;
 
1563
        char **merr;
 
1564
 
 
1565
        if (err) {
 
1566
                merr = &_merr;
 
1567
                *merr = NULL;
 
1568
        }
 
1569
        else
 
1570
                merr = NULL;
 
1571
 
 
1572
        /* Look for pattern in the reference. */
 
1573
        list_for_each_entry(elt, &ref->head, list) {
 
1574
                if (strcmp(key, elt->pattern) == 0) {
 
1575
                        if (!pat_ref_set_elt(ref, elt, value, merr)) {
 
1576
                                if (!found)
 
1577
                                        *err = *merr;
 
1578
                                else {
 
1579
                                        memprintf(err, "%s, %s", *err, *merr);
 
1580
                                        free(*merr);
 
1581
                                        *merr = NULL;
 
1582
                                }
 
1583
                        }
 
1584
                        found = 1;
 
1585
                }
 
1586
        }
 
1587
 
 
1588
        if (!found) {
 
1589
                memprintf(err, "entry not found");
 
1590
                return 0;
 
1591
        }
 
1592
        return 1;
 
1593
}
 
1594
 
 
1595
/* This function create new reference. <ref> is the reference name.
 
1596
 * <flags> are PAT_REF_*. /!\ The reference is not checked, and must
 
1597
 * be unique. The user must check the reference with "pat_ref_lookup()"
 
1598
 * before calling this function. If the fucntion fail, it return NULL,
 
1599
 * else return new struct pat_ref.
 
1600
 */
 
1601
struct pat_ref *pat_ref_new(const char *reference, const char *display, unsigned int flags)
 
1602
{
 
1603
        struct pat_ref *ref;
 
1604
 
 
1605
        ref = malloc(sizeof(*ref));
 
1606
        if (!ref)
 
1607
                return NULL;
 
1608
 
 
1609
        if (display) {
 
1610
                ref->display = strdup(display);
 
1611
                if (!ref->display) {
 
1612
                        free(ref);
 
1613
                        return NULL;
 
1614
                }
 
1615
        }
 
1616
        else
 
1617
                ref->display = NULL;
 
1618
 
 
1619
        ref->reference = strdup(reference);
 
1620
        if (!ref->reference) {
 
1621
                free(ref->display);
 
1622
                free(ref);
 
1623
                return NULL;
 
1624
        }
 
1625
 
 
1626
        ref->flags = flags;
 
1627
        ref->unique_id = -1;
 
1628
 
 
1629
        LIST_INIT(&ref->head);
 
1630
        LIST_INIT(&ref->pat);
 
1631
 
 
1632
        LIST_ADDQ(&pattern_reference, &ref->list);
 
1633
 
 
1634
        return ref;
 
1635
}
 
1636
 
 
1637
/* This function create new reference. <unique_id> is the unique id. If
 
1638
 * the value of <unique_id> is -1, the unique id is calculated later.
 
1639
 * <flags> are PAT_REF_*. /!\ The reference is not checked, and must
 
1640
 * be unique. The user must check the reference with "pat_ref_lookup()"
 
1641
 * or pat_ref_lookupid before calling this function. If the function
 
1642
 * fail, it return NULL, else return new struct pat_ref.
 
1643
 */
 
1644
struct pat_ref *pat_ref_newid(int unique_id, const char *display, unsigned int flags)
 
1645
{
 
1646
        struct pat_ref *ref;
 
1647
 
 
1648
        ref = malloc(sizeof(*ref));
 
1649
        if (!ref)
 
1650
                return NULL;
 
1651
 
 
1652
        if (display) {
 
1653
                ref->display = strdup(display);
 
1654
                if (!ref->display) {
 
1655
                        free(ref);
 
1656
                        return NULL;
 
1657
                }
 
1658
        }
 
1659
        else
 
1660
                ref->display = NULL;
 
1661
 
 
1662
        ref->reference = NULL;
 
1663
        ref->flags = flags;
 
1664
        ref->unique_id = unique_id;
 
1665
        LIST_INIT(&ref->head);
 
1666
        LIST_INIT(&ref->pat);
 
1667
 
 
1668
        LIST_ADDQ(&pattern_reference, &ref->list);
 
1669
 
 
1670
        return ref;
 
1671
}
 
1672
 
 
1673
/* This function adds entry to <ref>. It can failed with memory error.
 
1674
 * If the function fails, it returns 0.
 
1675
 */
 
1676
int pat_ref_append(struct pat_ref *ref, char *pattern, char *sample, int line)
 
1677
{
 
1678
        struct pat_ref_elt *elt;
 
1679
 
 
1680
        elt = malloc(sizeof(*elt));
 
1681
        if (!elt)
 
1682
                return 0;
 
1683
 
 
1684
        elt->line = line;
 
1685
 
 
1686
        elt->pattern = strdup(pattern);
 
1687
        if (!elt->pattern) {
 
1688
                free(elt);
 
1689
                return 0;
 
1690
        }
 
1691
 
 
1692
        if (sample) {
 
1693
                elt->sample = strdup(sample);
 
1694
                if (!elt->sample) {
 
1695
                        free(elt->pattern);
 
1696
                        free(elt);
 
1697
                        return 0;
 
1698
                }
 
1699
        }
 
1700
        else
 
1701
                elt->sample = NULL;
 
1702
 
 
1703
        LIST_ADDQ(&ref->head, &elt->list);
 
1704
 
 
1705
        return 1;
 
1706
}
 
1707
 
 
1708
/* This function create sample found in <elt>, parse the pattern also
 
1709
 * found in <elt> and insert it in <expr>. The function copy <patflags>
 
1710
 * in <expr>. If the function fails, it returns0 and <err> is filled.
 
1711
 * In succes case, the function returns 1.
 
1712
 */
 
1713
static inline
 
1714
int pat_ref_push(struct pat_ref_elt *elt, struct pattern_expr *expr,
 
1715
                 int patflags, char **err)
 
1716
{
 
1717
        struct sample_storage *smp;
 
1718
        struct pattern pattern;
 
1719
 
 
1720
        /* Create sample */
 
1721
        if (elt->sample && expr->pat_head->parse_smp) {
 
1722
                /* New sample. */
 
1723
                smp = malloc(sizeof(*smp));
 
1724
                if (!smp)
 
1725
                        return 0;
 
1726
 
 
1727
                /* Parse value. */
 
1728
                if (!expr->pat_head->parse_smp(elt->sample, smp)) {
 
1729
                        memprintf(err, "unable to parse '%s'", elt->sample);
 
1730
                        free(smp);
 
1731
                        return 0;
 
1732
                }
 
1733
 
 
1734
        }
 
1735
        else
 
1736
                smp = NULL;
 
1737
 
 
1738
        /* initialise pattern */
 
1739
        memset(&pattern, 0, sizeof(pattern));
 
1740
        pattern.smp = smp;
 
1741
        pattern.ref = elt;
 
1742
 
 
1743
        /* parse pattern */
 
1744
        if (!expr->pat_head->parse(elt->pattern, &pattern, expr->mflags, err)) {
 
1745
                free(smp);
 
1746
                return 0;
 
1747
        }
 
1748
 
 
1749
        /* index pattern */
 
1750
        if (!expr->pat_head->index(expr, &pattern, err)) {
 
1751
                free(smp);
 
1752
                return 0;
 
1753
        }
 
1754
 
 
1755
        return 1;
 
1756
}
 
1757
 
 
1758
/* This function adds entry to <ref>. It can failed with memory error. The new
 
1759
 * entry is added at all the pattern_expr registered in this reference. The
 
1760
 * function stop on the first error encountered. It returns 0 and err is
 
1761
 * filled. If an error is encountered, the complete add operation is cancelled.
 
1762
 * If the insertion is a success the function returns 1.
 
1763
 */
 
1764
int pat_ref_add(struct pat_ref *ref,
 
1765
                const char *pattern, const char *sample,
 
1766
                char **err)
 
1767
{
 
1768
        struct pat_ref_elt *elt;
 
1769
        struct pattern_expr *expr;
 
1770
 
 
1771
        elt = malloc(sizeof(*elt));
 
1772
        if (!elt) {
 
1773
                memprintf(err, "out of memory error");
 
1774
                return 0;
 
1775
        }
 
1776
 
 
1777
        elt->line = -1;
 
1778
 
 
1779
        elt->pattern = strdup(pattern);
 
1780
        if (!elt->pattern) {
 
1781
                free(elt);
 
1782
                memprintf(err, "out of memory error");
 
1783
                return 0;
 
1784
        }
 
1785
 
 
1786
        if (sample) {
 
1787
                elt->sample = strdup(sample);
 
1788
                if (!elt->sample) {
 
1789
                        free(elt->pattern);
 
1790
                        free(elt);
 
1791
                        memprintf(err, "out of memory error");
 
1792
                        return 0;
 
1793
                }
 
1794
        }
 
1795
        else
 
1796
                elt->sample = NULL;
 
1797
 
 
1798
        LIST_ADDQ(&ref->head, &elt->list);
 
1799
 
 
1800
        list_for_each_entry(expr, &ref->pat, list) {
 
1801
                if (!pat_ref_push(elt, expr, 0, err)) {
 
1802
                        /* If the insertion fails, try to delete all the added entries. */
 
1803
                        pat_ref_delete_by_id(ref, elt);
 
1804
                        return 0;
 
1805
                }
 
1806
        }
 
1807
        return 1;
 
1808
}
 
1809
 
 
1810
/* This function prune <ref>, replace all reference by the references
 
1811
 * of <replace>, and reindex all the news values.
 
1812
 *
 
1813
 * The pattern are loaded in best effort and the errors are ignored,
 
1814
 * but writed in the logs.
 
1815
 */
 
1816
void pat_ref_reload(struct pat_ref *ref, struct pat_ref *replace)
 
1817
{
 
1818
        struct pattern_expr *expr;
 
1819
        struct pat_ref_elt *elt;
 
1820
        char *err = NULL;
 
1821
 
 
1822
        pat_ref_prune(ref);
 
1823
 
 
1824
        LIST_ADD(&replace->head, &ref->head);
 
1825
        LIST_DEL(&replace->head);
 
1826
 
 
1827
        list_for_each_entry(elt, &ref->head, list) {
 
1828
                list_for_each_entry(expr, &ref->pat, list) {
 
1829
                        if (!pat_ref_push(elt, expr, 0, &err)) {
 
1830
                                send_log(NULL, LOG_NOTICE, "%s", err);
 
1831
                                free(err);
 
1832
                                err = NULL;
 
1833
                        }
 
1834
                }
 
1835
        }
 
1836
}
 
1837
 
 
1838
/* This function prune all entries of <ref>. This function
 
1839
 * prune the associated pattern_expr.
 
1840
 */
 
1841
void pat_ref_prune(struct pat_ref *ref)
 
1842
{
 
1843
        struct pat_ref_elt *elt, *safe;
 
1844
        struct pattern_expr *expr;
 
1845
 
 
1846
        list_for_each_entry_safe(elt, safe, &ref->head, list) {
 
1847
                LIST_DEL(&elt->list);
 
1848
                free(elt->pattern);
 
1849
                free(elt->sample);
 
1850
                free(elt);
 
1851
        }
 
1852
 
 
1853
        list_for_each_entry(expr, &ref->pat, list)
 
1854
                expr->pat_head->prune(expr);
 
1855
}
 
1856
 
 
1857
/* This function lookup for existing reference <ref> in pattern_head <head>. */
 
1858
struct pattern_expr *pattern_lookup_expr(struct pattern_head *head, struct pat_ref *ref)
 
1859
{
 
1860
        struct pattern_expr_list *expr;
 
1861
 
 
1862
        list_for_each_entry(expr, &head->head, list)
 
1863
                if (expr->expr->ref == ref)
 
1864
                        return expr->expr;
 
1865
        return NULL;
 
1866
}
 
1867
 
 
1868
/* This function create new pattern_expr associated to the reference <ref>.
 
1869
 * <ref> can be NULL. If an error is occured, the function returns NULL and
 
1870
 * <err> is filled. Otherwise, the function returns new pattern_expr linked
 
1871
 * with <head> and <ref>.
 
1872
 */
 
1873
struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref, char **err)
 
1874
{
 
1875
        struct pattern_expr *expr;
 
1876
        struct pattern_expr_list *list;
 
1877
 
 
1878
        /* Memory and initialization of the chain element. */
 
1879
        list = malloc(sizeof(*list));
 
1880
        if (!list) {
 
1881
                memprintf(err, "out of memory");
 
1882
                return NULL;
 
1883
        }
 
1884
 
 
1885
        /* Look for existing similar expr. No that only the index, parse and
 
1886
         * parse_smp function must be identical for having similar pattern.
 
1887
         * The other function depends of theses first.
 
1888
         */
 
1889
        if (ref) {
 
1890
                list_for_each_entry(expr, &ref->pat, list)
 
1891
                        if (expr->pat_head->index     == head->index &&
 
1892
                            expr->pat_head->parse     == head->parse &&
 
1893
                            expr->pat_head->parse_smp == head->parse_smp)
 
1894
                                break;
 
1895
                if (&expr->list == &ref->pat)
 
1896
                        expr = NULL;
 
1897
        }
 
1898
        else
 
1899
                expr = NULL;
 
1900
 
 
1901
        /* If no similar expr was found, we create new expr. */
 
1902
        if (!expr) {
 
1903
                /* Get a lot of memory for the expr struct. */
 
1904
                expr = malloc(sizeof(*expr));
 
1905
                if (!expr) {
 
1906
                        memprintf(err, "out of memory");
 
1907
                        return NULL;
 
1908
                }
 
1909
 
 
1910
                /* Initialize this new expr. */
 
1911
                pattern_init_expr(expr);
 
1912
 
 
1913
                /* This new pattern expression reference one of his heads. */
 
1914
                expr->pat_head = head;
 
1915
 
 
1916
                /* Link with ref, or to self to facilitate LIST_DEL() */
 
1917
                if (ref)
 
1918
                        LIST_ADDQ(&ref->pat, &expr->list);
 
1919
                else
 
1920
                        LIST_INIT(&expr->list);
 
1921
 
 
1922
                expr->ref = ref;
 
1923
 
 
1924
                /* We must free this pattern if it is no more used. */
 
1925
                list->do_free = 1;
 
1926
        }
 
1927
        else {
 
1928
                /* If the pattern used already exists, it is already linked
 
1929
                 * with ref and we must not free it.
 
1930
                 */
 
1931
                list->do_free = 0;
 
1932
        }
 
1933
 
 
1934
        /* The new list element reference the pattern_expr. */
 
1935
        list->expr = expr;
 
1936
 
 
1937
        /* Link the list element with the pattern_head. */
 
1938
        LIST_ADDQ(&head->head, &list->list);
447
1939
        return expr;
448
 
 
449
 
out_error:
450
 
        /* TODO: prune_pattern_expr(expr); */
451
 
        return NULL;
452
 
}
453
 
 
454
 
/*
455
 
 * Process a fetch + format conversion of defined by the pattern expression <expr>
456
 
 * on request or response considering the <dir> parameter.
457
 
 * Returns a pointer on a typed pattern structure containing the result or NULL if
458
 
 * pattern is not found or when format conversion failed.
459
 
 *  If <p> is not null, function returns results in structure pointed by <p>.
460
 
 *  If <p> is null, functions returns a pointer on a static pattern structure.
461
 
 */
462
 
struct pattern *pattern_process(struct proxy *px, struct session *l4, void *l7, int dir,
463
 
                                struct pattern_expr *expr, struct pattern *p)
464
 
{
465
 
        struct pattern_conv_expr *conv_expr;
466
 
 
467
 
        if (p == NULL)
468
 
                p = &spattern;
469
 
 
470
 
        if (!expr->fetch->process(px, l4, l7, dir, expr->arg, expr->arg_len, &p->data))
471
 
                return NULL;
472
 
 
473
 
        p->type = expr->fetch->out_type;
474
 
 
475
 
        list_for_each_entry(conv_expr, &expr->conv_exprs, list) {
476
 
                if (!pattern_casts[p->type][conv_expr->conv->in_type](&p->data))
477
 
                        return NULL;
478
 
 
479
 
                p->type = conv_expr->conv->in_type;
480
 
                if (!conv_expr->conv->process(conv_expr->arg_p, conv_expr->arg_i, &p->data))
481
 
                        return NULL;
482
 
 
483
 
                p->type = conv_expr->conv->out_type;
484
 
        }
485
 
        return p;
486
 
}
487
 
 
488
 
/*
489
 
 *  Process a fetch + format conversion of defined by the pattern expression <expr>
490
 
 *  on request or response considering the <dir> parameter.
491
 
 *  Returns a pointer on a static tablekey  structure of type <table_type> of
492
 
 *  the converted result.
493
 
 */
494
 
struct stktable_key *pattern_process_key(struct proxy *px, struct session *l4, void *l7, int dir,
495
 
                                         struct pattern_expr *expr, unsigned long table_type)
496
 
{
497
 
        struct pattern *ptrn;
498
 
 
499
 
        ptrn = pattern_process(px, l4, l7, dir, expr, NULL);
500
 
        if (!ptrn)
501
 
                return NULL;
502
 
 
503
 
        stable_key.key_len = (size_t)-1;
504
 
        stable_key.key = pattern_keys[ptrn->type][table_type](&ptrn->data, &stable_key.data, &stable_key.key_len);
505
 
 
506
 
        if (!stable_key.key)
507
 
                return NULL;
508
 
 
509
 
        return &stable_key;
510
 
}
511
 
 
512
 
/*
513
 
 * Returns 1 if pattern expression <expr> result cannot be converted to table key of
514
 
 * type <table_type> .
515
 
 *
516
 
 * Used in configuration check
517
 
 */
518
 
int pattern_notusable_key(struct pattern_expr *expr, unsigned long table_type)
519
 
{
520
 
 
521
 
        if (table_type >= STKTABLE_TYPES)
522
 
                return 1;
523
 
 
524
 
        if (LIST_ISEMPTY(&expr->conv_exprs)) {
525
 
                if (!pattern_keys[expr->fetch->out_type][table_type])
526
 
                        return 1;
527
 
        } else {
528
 
                struct pattern_conv_expr *conv_expr;
529
 
                conv_expr = LIST_PREV(&expr->conv_exprs, typeof(conv_expr), list);
530
 
 
531
 
                if (!pattern_keys[conv_expr->conv->out_type][table_type])
532
 
                        return 1;
533
 
        }
534
 
        return 0;
535
 
}
536
 
 
537
 
/* Converts an argument string to an IPv4 mask stored in network byte order in
538
 
 * arg_i. Returns non-zero in case of success, 0 on error.
539
 
 */
540
 
static int pattern_conv_arg_to_ipmask(const char *arg_str, void **arg_p, int *arg_i)
541
 
{
542
 
        struct in_addr mask;
543
 
 
544
 
        if (!str2mask(arg_str, &mask))
545
 
                return 0;
546
 
 
547
 
        *arg_i = mask.s_addr;
548
 
        return 1;
549
 
}
550
 
 
551
 
/*****************************************************************/
552
 
/*    Pattern format convert functions                           */
553
 
/*****************************************************************/
554
 
 
555
 
static int pattern_conv_str2lower(const void *arg_p, int arg_i, union pattern_data *data)
556
 
{
557
 
        int i;
558
 
 
559
 
        for (i = 0; i < data->str.len; i++) {
560
 
                if ((data->str.str[i] >= 'A') && (data->str.str[i] <= 'Z'))
561
 
                        data->str.str[i] += 'a' - 'A';
562
 
        }
563
 
        return 1;
564
 
}
565
 
 
566
 
static int pattern_conv_str2upper(const void *arg_p, int arg_i, union pattern_data *data)
567
 
{
568
 
        int i;
569
 
 
570
 
        for (i = 0; i < data->str.len; i++) {
571
 
                if ((data->str.str[i] >= 'a') && (data->str.str[i] <= 'z'))
572
 
                        data->str.str[i] += 'A' - 'a';
573
 
        }
574
 
        return 1;
575
 
}
576
 
 
577
 
/* takes the netmask in arg_i */
578
 
static int pattern_conv_ipmask(const void *arg_p, int arg_i, union pattern_data *data)
579
 
{
580
 
        data->ip.s_addr &= arg_i;
581
 
        return 1;
582
 
}
583
 
 
584
 
/* Note: must not be declared <const> as its list will be overwritten */
585
 
static struct pattern_conv_kw_list pattern_conv_kws = {{ },{
586
 
        { "upper",       pattern_conv_str2upper, PATTERN_TYPE_STRING, PATTERN_TYPE_STRING },
587
 
        { "lower",       pattern_conv_str2lower, PATTERN_TYPE_STRING, PATTERN_TYPE_STRING },
588
 
        { "ipmask",      pattern_conv_ipmask, PATTERN_TYPE_IP, PATTERN_TYPE_IP, pattern_conv_arg_to_ipmask },
589
 
        { NULL, NULL, 0, 0 },
590
 
}};
591
 
 
592
 
__attribute__((constructor))
593
 
static void __pattern_init(void)
594
 
{
595
 
        /* register pattern format convert keywords */
596
 
        pattern_register_convs(&pattern_conv_kws);
 
1940
}
 
1941
 
 
1942
/* Reads patterns from a file. If <err_msg> is non-NULL, an error message will
 
1943
 * be returned there on errors and the caller will have to free it.
 
1944
 *
 
1945
 * The file contains one key + value per line. Lines which start with '#' are
 
1946
 * ignored, just like empty lines. Leading tabs/spaces are stripped. The key is
 
1947
 * then the first "word" (series of non-space/tabs characters), and the value is
 
1948
 * what follows this series of space/tab till the end of the line excluding
 
1949
 * trailing spaces/tabs.
 
1950
 *
 
1951
 * Example :
 
1952
 *
 
1953
 *     # this is a comment and is ignored
 
1954
 *        62.212.114.60     1wt.eu      \n
 
1955
 *     <-><-----------><---><----><---->
 
1956
 *      |       |        |     |     `--- trailing spaces ignored
 
1957
 *      |       |        |      `-------- value
 
1958
 *      |       |        `--------------- middle spaces ignored
 
1959
 *      |       `------------------------ key
 
1960
 *      `-------------------------------- leading spaces ignored
 
1961
 *
 
1962
 * Return non-zero in case of succes, otherwise 0.
 
1963
 */
 
1964
int pat_ref_read_from_file_smp(struct pat_ref *ref, const char *filename, char **err)
 
1965
{
 
1966
        FILE *file;
 
1967
        char *c;
 
1968
        int ret = 0;
 
1969
        int line = 0;
 
1970
        char *key_beg;
 
1971
        char *key_end;
 
1972
        char *value_beg;
 
1973
        char *value_end;
 
1974
 
 
1975
        file = fopen(filename, "r");
 
1976
        if (!file) {
 
1977
                memprintf(err, "failed to open pattern file <%s>", filename);
 
1978
                return 0;
 
1979
        }
 
1980
 
 
1981
        /* now parse all patterns. The file may contain only one pattern
 
1982
         * followed by one value per line. The start spaces, separator spaces
 
1983
         * and and spaces are stripped. Each can contain comment started by '#'
 
1984
         */
 
1985
        while (fgets(trash.str, trash.size, file) != NULL) {
 
1986
                line++;
 
1987
                c = trash.str;
 
1988
 
 
1989
                /* ignore lines beginning with a dash */
 
1990
                if (*c == '#')
 
1991
                        continue;
 
1992
 
 
1993
                /* strip leading spaces and tabs */
 
1994
                while (*c == ' ' || *c == '\t')
 
1995
                        c++;
 
1996
 
 
1997
                /* empty lines are ignored too */
 
1998
                if (*c == '\0' || *c == '\r' || *c == '\n')
 
1999
                        continue;
 
2000
 
 
2001
                /* look for the end of the key */
 
2002
                key_beg = c;
 
2003
                while (*c && *c != ' ' && *c != '\t' && *c != '\n' && *c != '\r')
 
2004
                        c++;
 
2005
 
 
2006
                key_end = c;
 
2007
 
 
2008
                /* strip middle spaces and tabs */
 
2009
                while (*c == ' ' || *c == '\t')
 
2010
                        c++;
 
2011
 
 
2012
                /* look for the end of the value, it is the end of the line */
 
2013
                value_beg = c;
 
2014
                while (*c && *c != '\n' && *c != '\r')
 
2015
                        c++;
 
2016
                value_end = c;
 
2017
 
 
2018
                /* trim possibly trailing spaces and tabs */
 
2019
                while (value_end > value_beg && (value_end[-1] == ' ' || value_end[-1] == '\t'))
 
2020
                        value_end--;
 
2021
 
 
2022
                /* set final \0 and check entries */
 
2023
                *key_end = '\0';
 
2024
                *value_end = '\0';
 
2025
 
 
2026
                /* insert values */
 
2027
                if (!pat_ref_append(ref, key_beg, value_beg, line)) {
 
2028
                        memprintf(err, "out of memory");
 
2029
                        goto out_close;
 
2030
                }
 
2031
        }
 
2032
 
 
2033
        /* succes */
 
2034
        ret = 1;
 
2035
 
 
2036
 out_close:
 
2037
        fclose(file);
 
2038
        return ret;
 
2039
}
 
2040
 
 
2041
/* Reads patterns from a file. If <err_msg> is non-NULL, an error message will
 
2042
 * be returned there on errors and the caller will have to free it.
 
2043
 */
 
2044
int pat_ref_read_from_file(struct pat_ref *ref, const char *filename, char **err)
 
2045
{
 
2046
        FILE *file;
 
2047
        char *c;
 
2048
        char *arg;
 
2049
        int ret = 0;
 
2050
        int line = 0;
 
2051
 
 
2052
        file = fopen(filename, "r");
 
2053
        if (!file) {
 
2054
                memprintf(err, "failed to open pattern file <%s>", filename);
 
2055
                return 0;
 
2056
        }
 
2057
 
 
2058
        /* now parse all patterns. The file may contain only one pattern per
 
2059
         * line. If the line contains spaces, they will be part of the pattern.
 
2060
         * The pattern stops at the first CR, LF or EOF encountered.
 
2061
         */
 
2062
        while (fgets(trash.str, trash.size, file) != NULL) {
 
2063
                line++;
 
2064
                c = trash.str;
 
2065
 
 
2066
                /* ignore lines beginning with a dash */
 
2067
                if (*c == '#')
 
2068
                        continue;
 
2069
 
 
2070
                /* strip leading spaces and tabs */
 
2071
                while (*c == ' ' || *c == '\t')
 
2072
                        c++;
 
2073
 
 
2074
 
 
2075
                arg = c;
 
2076
                while (*c && *c != '\n' && *c != '\r')
 
2077
                        c++;
 
2078
                *c = 0;
 
2079
 
 
2080
                /* empty lines are ignored too */
 
2081
                if (c == arg)
 
2082
                        continue;
 
2083
 
 
2084
                if (!pat_ref_append(ref, arg, NULL, line)) {
 
2085
                        memprintf(err, "out of memory when loading patterns from file <%s>", filename);
 
2086
                        goto out_close;
 
2087
                }
 
2088
        }
 
2089
 
 
2090
        ret = 1; /* success */
 
2091
 
 
2092
 out_close:
 
2093
        fclose(file);
 
2094
        return ret;
 
2095
}
 
2096
 
 
2097
int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
 
2098
                           const char *filename, int patflags, int load_smp,
 
2099
                           char **err, const char *file, int line)
 
2100
{
 
2101
        struct pat_ref *ref;
 
2102
        struct pattern_expr *expr;
 
2103
        struct pat_ref_elt *elt;
 
2104
 
 
2105
        /* Lookup for the existing reference. */
 
2106
        ref = pat_ref_lookup(filename);
 
2107
 
 
2108
        /* If the reference doesn't exists, create it and load associated file. */
 
2109
        if (!ref) {
 
2110
                chunk_printf(&trash,
 
2111
                             "pattern loaded from file '%s' used by %s at file '%s' line %d",
 
2112
                             filename, refflags & PAT_REF_MAP ? "map" : "acl", file, line);
 
2113
 
 
2114
                ref = pat_ref_new(filename, trash.str, refflags);
 
2115
                if (!ref) {
 
2116
                        memprintf(err, "out of memory");
 
2117
                        return 0;
 
2118
                }
 
2119
 
 
2120
                if (load_smp) {
 
2121
                        ref->flags |= PAT_REF_SMP;
 
2122
                        if (!pat_ref_read_from_file_smp(ref, filename, err))
 
2123
                                return 0;
 
2124
                }
 
2125
                else {
 
2126
                        if (!pat_ref_read_from_file(ref, filename, err))
 
2127
                                return 0;
 
2128
                }
 
2129
        }
 
2130
        else {
 
2131
                /* The reference already exists, check the map compatibility. */
 
2132
 
 
2133
                /* If the load require samples and the flag PAT_REF_SMP is not set,
 
2134
                 * the reference doesn't contain sample, and cannot be used.
 
2135
                 */
 
2136
                if (load_smp) {
 
2137
                        if (!(ref->flags & PAT_REF_SMP)) {
 
2138
                                memprintf(err, "The file \"%s\" is already used as one column file "
 
2139
                                               "and cannot be used by as two column file.",
 
2140
                                               filename);
 
2141
                                return 0;
 
2142
                        }
 
2143
                }
 
2144
                else {
 
2145
                        /* The load doesn't require samples. If the flag PAT_REF_SMP is
 
2146
                         * set, the reference contains a sample, and cannot be used.
 
2147
                         */
 
2148
                        if (ref->flags & PAT_REF_SMP) {
 
2149
                                memprintf(err, "The file \"%s\" is already used as two column file "
 
2150
                                               "and cannot be used by as one column file.",
 
2151
                                               filename);
 
2152
                                return 0;
 
2153
                        }
 
2154
                }
 
2155
 
 
2156
                /* Extends display */
 
2157
                chunk_printf(&trash, "%s", ref->display);
 
2158
                chunk_appendf(&trash, ", by %s at file '%s' line %d",
 
2159
                              refflags & PAT_REF_MAP ? "map" : "acl", file, line);
 
2160
                free(ref->display);
 
2161
                ref->display = strdup(trash.str);
 
2162
                if (!ref->display) {
 
2163
                        memprintf(err, "out of memory");
 
2164
                        return 0;
 
2165
                }
 
2166
 
 
2167
                /* Merge flags. */
 
2168
                ref->flags |= refflags;
 
2169
        }
 
2170
 
 
2171
        /* Now, we can loading patterns from the reference. */
 
2172
 
 
2173
        /* Lookup for existing reference in the head. If the reference
 
2174
         * doesn't exists, create it.
 
2175
         */
 
2176
        expr = pattern_lookup_expr(head, ref);
 
2177
        if (!expr || (expr->mflags != patflags)) {
 
2178
                expr = pattern_new_expr(head, ref, err);
 
2179
                if (!expr)
 
2180
                        return 0;
 
2181
                expr->mflags = patflags;
 
2182
        }
 
2183
 
 
2184
        /* Load reference content in the pattern expression. */
 
2185
        list_for_each_entry(elt, &ref->head, list) {
 
2186
                if (!pat_ref_push(elt, expr, patflags, err)) {
 
2187
                        if (elt->line > 0)
 
2188
                                memprintf(err, "%s at line %d of file '%s'",
 
2189
                                          *err, elt->line, filename);
 
2190
                        return 0;
 
2191
                }
 
2192
        }
 
2193
 
 
2194
        return 1;
 
2195
}
 
2196
 
 
2197
/* This function executes a pattern match on a sample. It applies pattern <expr>
 
2198
 * to sample <smp>. The function returns NULL if the sample dont match. It returns
 
2199
 * non-null if the sample match. If <fill> is true and the sample match, the
 
2200
 * function returns the matched pattern. In many cases, this pattern can be a
 
2201
 * static buffer.
 
2202
 */
 
2203
struct pattern *pattern_exec_match(struct pattern_head *head, struct sample *smp, int fill)
 
2204
{
 
2205
        struct pattern_expr_list *list;
 
2206
        struct pattern *pat;
 
2207
 
 
2208
        if (!head->match) {
 
2209
                if (fill) {
 
2210
                        static_pattern.smp = NULL;
 
2211
                        static_pattern.ref = NULL;
 
2212
                        static_pattern.sflags = 0;
 
2213
                        static_pattern.type = SMP_T_UINT;
 
2214
                        static_pattern.val.i = 1;
 
2215
                }
 
2216
                return &static_pattern;
 
2217
        }
 
2218
 
 
2219
        /* convert input to string */
 
2220
        if (!sample_convert(smp, head->expect_type))
 
2221
                return NULL;
 
2222
 
 
2223
        list_for_each_entry(list, &head->head, list) {
 
2224
                pat = head->match(smp, list->expr, fill);
 
2225
                if (pat)
 
2226
                        return pat;
 
2227
        }
 
2228
        return NULL;
 
2229
}
 
2230
 
 
2231
/* This function prune the pattern expression. */
 
2232
void pattern_prune(struct pattern_head *head)
 
2233
{
 
2234
        struct pattern_expr_list *list, *safe;
 
2235
 
 
2236
        list_for_each_entry_safe(list, safe, &head->head, list) {
 
2237
                LIST_DEL(&list->list);
 
2238
                if (list->do_free) {
 
2239
                        LIST_DEL(&list->expr->list);
 
2240
                        head->prune(list->expr);
 
2241
                        free(list->expr);
 
2242
                }
 
2243
                free(list);
 
2244
        }
 
2245
}
 
2246
 
 
2247
/* This function lookup for a pattern matching the <key> and return a
 
2248
 * pointer to a pointer of the sample stoarge. If the <key> dont match,
 
2249
 * the function returns NULL. If the key cannot be parsed, the function
 
2250
 * fill <err>.
 
2251
 */
 
2252
struct sample_storage **pattern_find_smp(struct pattern_expr *expr, struct pat_ref_elt *ref)
 
2253
{
 
2254
        struct ebmb_node *node;
 
2255
        struct pattern_tree *elt;
 
2256
        struct pattern_list *pat;
 
2257
 
 
2258
        for (node = ebmb_first(&expr->pattern_tree);
 
2259
             node;
 
2260
             node = ebmb_next(node)) {
 
2261
                elt = container_of(node, struct pattern_tree, node);
 
2262
                if (elt->ref == ref)
 
2263
                        return &elt->smp;
 
2264
        }
 
2265
 
 
2266
        for (node = ebmb_first(&expr->pattern_tree_2);
 
2267
             node;
 
2268
             node = ebmb_next(node)) {
 
2269
                elt = container_of(node, struct pattern_tree, node);
 
2270
                if (elt->ref == ref)
 
2271
                        return &elt->smp;
 
2272
        }
 
2273
 
 
2274
        list_for_each_entry(pat, &expr->patterns, list)
 
2275
                if (pat->pat.ref == ref)
 
2276
                        return &pat->pat.smp;
 
2277
 
 
2278
        return NULL;
 
2279
}
 
2280
 
 
2281
/* This function search all the pattern matching the <key> and delete it.
 
2282
 * If the parsing of the input key fails, the function returns 0 and the
 
2283
 * <err> is filled, else return 1;
 
2284
 */
 
2285
int pattern_delete(struct pattern_expr *expr, struct pat_ref_elt *ref)
 
2286
{
 
2287
        expr->pat_head->delete(expr, ref);
 
2288
        return 1;
 
2289
}
 
2290
 
 
2291
/* This function finalize the configuration parsing. Its set all the
 
2292
 * automatic ids
 
2293
 */
 
2294
void pattern_finalize_config(void)
 
2295
{
 
2296
        int i = 0;
 
2297
        struct pat_ref *ref, *ref2, *ref3;
 
2298
        struct list pr = LIST_HEAD_INIT(pr);
 
2299
 
 
2300
        list_for_each_entry(ref, &pattern_reference, list) {
 
2301
                if (ref->unique_id == -1) {
 
2302
                        /* Look for the first free id. */
 
2303
                        while (1) {
 
2304
                                list_for_each_entry(ref2, &pattern_reference, list) {
 
2305
                                        if (ref2->unique_id == i) {
 
2306
                                                i++;
 
2307
                                                break;
 
2308
                                        }
 
2309
                                }
 
2310
                                if (&ref2->list == &pattern_reference)
 
2311
                                        break;
 
2312
                        }
 
2313
 
 
2314
                        /* Uses the unique id and increment it for the next entry. */
 
2315
                        ref->unique_id = i;
 
2316
                        i++;
 
2317
                }
 
2318
        }
 
2319
 
 
2320
        /* This sort the reference list by id. */
 
2321
        list_for_each_entry_safe(ref, ref2, &pattern_reference, list) {
 
2322
                LIST_DEL(&ref->list);
 
2323
                list_for_each_entry(ref3, &pr, list) {
 
2324
                        if (ref->unique_id < ref3->unique_id) {
 
2325
                                LIST_ADDQ(&ref3->list, &ref->list);
 
2326
                                break;
 
2327
                        }
 
2328
                }
 
2329
                if (&ref3->list == &pr)
 
2330
                        LIST_ADDQ(&pr, &ref->list);
 
2331
        }
 
2332
 
 
2333
        /* swap root */
 
2334
        LIST_ADD(&pr, &pattern_reference);
 
2335
        LIST_DEL(&pr);
597
2336
}