Coverage Report

Created: 2026-07-16 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/haproxy/src/pattern.c
Line
Count
Source
1
/*
2
 * Pattern management functions.
3
 *
4
 * Copyright 2000-2013 Willy Tarreau <w@1wt.eu>
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version
9
 * 2 of the License, or (at your option) any later version.
10
 *
11
 */
12
13
#include <ctype.h>
14
#include <stdio.h>
15
#include <errno.h>
16
17
#include <import/cebs_tree.h>
18
#include <import/ceb32_tree.h>
19
#include <import/ebistree.h>
20
#include <import/ebpttree.h>
21
#include <import/ebsttree.h>
22
#include <import/lru.h>
23
24
#include <haproxy/api.h>
25
#include <haproxy/global.h>
26
#include <haproxy/log.h>
27
#include <haproxy/net_helper.h>
28
#include <haproxy/pattern.h>
29
#include <haproxy/regex.h>
30
#include <haproxy/sample.h>
31
#include <haproxy/tools.h>
32
#include <haproxy/xxhash.h>
33
34
35
/* Convenience macros for iterating over generations. */
36
#define pat_ref_gen_foreach(gen, ref)               \
37
0
  for (gen = cebu32_item_first(&ref->gen_root, gen_node, gen_id, struct pat_ref_gen); \
38
0
       gen;                   \
39
0
       gen = cebu32_item_next(&ref->gen_root, gen_node, gen_id, gen))
40
41
/* Safe variant that allows deleting an entry in the body of the loop. */
42
#define pat_ref_gen_foreach_safe(gen, next, ref)            \
43
0
  for (gen = cebu32_item_first(&ref->gen_root, gen_node, gen_id, struct pat_ref_gen); \
44
0
       gen && (next = cebu32_item_next(&ref->gen_root, gen_node, gen_id, gen), 1);  \
45
0
       gen = next)
46
47
const char *const pat_match_names[PAT_MATCH_NUM] = {
48
  [PAT_MATCH_FOUND] = "found",
49
  [PAT_MATCH_BOOL]  = "bool",
50
  [PAT_MATCH_INT]   = "int",
51
  [PAT_MATCH_IP]    = "ip",
52
  [PAT_MATCH_BIN]   = "bin",
53
  [PAT_MATCH_LEN]   = "len",
54
  [PAT_MATCH_STR]   = "str",
55
  [PAT_MATCH_BEG]   = "beg",
56
  [PAT_MATCH_SUB]   = "sub",
57
  [PAT_MATCH_DIR]   = "dir",
58
  [PAT_MATCH_DOM]   = "dom",
59
  [PAT_MATCH_END]   = "end",
60
  [PAT_MATCH_REG]   = "reg",
61
  [PAT_MATCH_REGM]  = "regm",
62
};
63
64
int (*const pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, int, char **) = {
65
  [PAT_MATCH_FOUND] = pat_parse_nothing,
66
  [PAT_MATCH_BOOL]  = pat_parse_nothing,
67
  [PAT_MATCH_INT]   = pat_parse_int,
68
  [PAT_MATCH_IP]    = pat_parse_ip,
69
  [PAT_MATCH_BIN]   = pat_parse_bin,
70
  [PAT_MATCH_LEN]   = pat_parse_int,
71
  [PAT_MATCH_STR]   = pat_parse_str,
72
  [PAT_MATCH_BEG]   = pat_parse_str,
73
  [PAT_MATCH_SUB]   = pat_parse_str,
74
  [PAT_MATCH_DIR]   = pat_parse_str,
75
  [PAT_MATCH_DOM]   = pat_parse_str,
76
  [PAT_MATCH_END]   = pat_parse_str,
77
  [PAT_MATCH_REG]   = pat_parse_reg,
78
  [PAT_MATCH_REGM]  = pat_parse_reg,
79
};
80
81
int (*const pat_index_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pattern *, char **) = {
82
  [PAT_MATCH_FOUND] = pat_idx_list_val,
83
  [PAT_MATCH_BOOL]  = pat_idx_list_val,
84
  [PAT_MATCH_INT]   = pat_idx_list_val,
85
  [PAT_MATCH_IP]    = pat_idx_tree_ip,
86
  [PAT_MATCH_BIN]   = pat_idx_list_ptr,
87
  [PAT_MATCH_LEN]   = pat_idx_list_val,
88
  [PAT_MATCH_STR]   = pat_idx_tree_str,
89
  [PAT_MATCH_BEG]   = pat_idx_tree_pfx,
90
  [PAT_MATCH_SUB]   = pat_idx_list_str,
91
  [PAT_MATCH_DIR]   = pat_idx_list_str,
92
  [PAT_MATCH_DOM]   = pat_idx_list_str,
93
  [PAT_MATCH_END]   = pat_idx_list_str,
94
  [PAT_MATCH_REG]   = pat_idx_list_reg,
95
  [PAT_MATCH_REGM]  = pat_idx_list_regm,
96
};
97
98
void (*const pat_prune_fcts[PAT_MATCH_NUM])(struct pattern_expr *) = {
99
  [PAT_MATCH_FOUND] = pat_prune_gen,
100
  [PAT_MATCH_BOOL]  = pat_prune_gen,
101
  [PAT_MATCH_INT]   = pat_prune_gen,
102
  [PAT_MATCH_IP]    = pat_prune_gen,
103
  [PAT_MATCH_BIN]   = pat_prune_gen,
104
  [PAT_MATCH_LEN]   = pat_prune_gen,
105
  [PAT_MATCH_STR]   = pat_prune_gen,
106
  [PAT_MATCH_BEG]   = pat_prune_gen,
107
  [PAT_MATCH_SUB]   = pat_prune_gen,
108
  [PAT_MATCH_DIR]   = pat_prune_gen,
109
  [PAT_MATCH_DOM]   = pat_prune_gen,
110
  [PAT_MATCH_END]   = pat_prune_gen,
111
  [PAT_MATCH_REG]   = pat_prune_gen,
112
  [PAT_MATCH_REGM]  = pat_prune_gen,
113
};
114
115
struct pattern *(*const pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern_expr *, int) = {
116
  [PAT_MATCH_FOUND] = NULL,
117
  [PAT_MATCH_BOOL]  = pat_match_nothing,
118
  [PAT_MATCH_INT]   = pat_match_int,
119
  [PAT_MATCH_IP]    = pat_match_ip,
120
  [PAT_MATCH_BIN]   = pat_match_bin,
121
  [PAT_MATCH_LEN]   = pat_match_len,
122
  [PAT_MATCH_STR]   = pat_match_str,
123
  [PAT_MATCH_BEG]   = pat_match_beg,
124
  [PAT_MATCH_SUB]   = pat_match_sub,
125
  [PAT_MATCH_DIR]   = pat_match_dir,
126
  [PAT_MATCH_DOM]   = pat_match_dom,
127
  [PAT_MATCH_END]   = pat_match_end,
128
  [PAT_MATCH_REG]   = pat_match_reg,
129
  [PAT_MATCH_REGM]  = pat_match_regm,
130
};
131
132
/* Just used for checking configuration compatibility */
133
int const pat_match_types[PAT_MATCH_NUM] = {
134
  [PAT_MATCH_FOUND] = SMP_T_SINT,
135
  [PAT_MATCH_BOOL]  = SMP_T_SINT,
136
  [PAT_MATCH_INT]   = SMP_T_SINT,
137
  [PAT_MATCH_IP]    = SMP_T_ADDR,
138
  [PAT_MATCH_BIN]   = SMP_T_BIN,
139
  [PAT_MATCH_LEN]   = SMP_T_STR,
140
  [PAT_MATCH_STR]   = SMP_T_STR,
141
  [PAT_MATCH_BEG]   = SMP_T_STR,
142
  [PAT_MATCH_SUB]   = SMP_T_STR,
143
  [PAT_MATCH_DIR]   = SMP_T_STR,
144
  [PAT_MATCH_DOM]   = SMP_T_STR,
145
  [PAT_MATCH_END]   = SMP_T_STR,
146
  [PAT_MATCH_REG]   = SMP_T_STR,
147
  [PAT_MATCH_REGM]  = SMP_T_STR,
148
};
149
150
/* this struct is used to return information */
151
static THREAD_LOCAL struct pattern static_pattern;
152
static THREAD_LOCAL struct sample_data static_sample_data;
153
154
/* This is the root of the list of all available pattern_ref values. */
155
struct list pattern_reference = LIST_HEAD_INIT(pattern_reference);
156
157
static THREAD_LOCAL struct lru64_head *pat_lru_tree;
158
static unsigned long long pat_lru_seed __read_mostly;
159
160
unsigned long long patterns_added = 0;
161
unsigned long long patterns_freed = 0;
162
163
/*
164
 *
165
 * The following functions are not exported and are used by internals process
166
 * of pattern matching
167
 *
168
 */
169
170
/* Background: Fast way to find a zero byte in a word
171
 * http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
172
 * hasZeroByte = (v - 0x01010101UL) & ~v & 0x80808080UL;
173
 *
174
 * To look for 4 different byte values, xor the word with those bytes and
175
 * then check for zero bytes:
176
 *
177
 * v = (((unsigned char)c * 0x1010101U) ^ delimiter)
178
 * where <delimiter> is the 4 byte values to look for (as an uint)
179
 * and <c> is the character that is being tested
180
 */
181
static inline unsigned int is_delimiter(unsigned char c, unsigned int mask)
182
0
{
183
0
  mask ^= (c * 0x01010101); /* propagate the char to all 4 bytes */
184
0
  return (mask - 0x01010101) & ~mask & 0x80808080U;
185
0
}
186
187
static inline unsigned int make_4delim(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4)
188
0
{
189
0
  return d1 << 24 | d2 << 16 | d3 << 8 | d4;
190
0
}
191
192
193
/*
194
 *
195
 * These functions are exported and may be used by any other component.
196
 *
197
 * The following functions are used for parsing pattern matching input value.
198
 * The <text> contain the string to be parsed. <pattern> must be a preallocated
199
 * pattern. The pat_parse_* functions fill this structure with the parsed value.
200
 * <err> is filled with an error message built with memprintf() function. It is
201
 * allowed to use a trash as a temporary storage for the returned pattern, as
202
 * the next call after these functions will be pat_idx_*.
203
 *
204
 * In success case, the pat_parse_* function returns 1. If the function
205
 * fails, it returns 0 and <err> is filled.
206
 */
207
208
/* ignore the current line */
209
int pat_parse_nothing(const char *text, struct pattern *pattern, int mflags, char **err)
210
0
{
211
0
  return 1;
212
0
}
213
214
/* Parse a string. The text is used directly without allocation. */
215
int pat_parse_str(const char *text, struct pattern *pattern, int mflags, char **err)
216
0
{
217
0
  pattern->type = SMP_T_STR;
218
0
  pattern->ptr.str = (char *)text;
219
0
  pattern->len = strlen(text);
220
0
  return 1;
221
0
}
222
223
/* Parse a binary written in hexa. The data is stored in the trash chunk. */
224
int pat_parse_bin(const char *text, struct pattern *pattern, int mflags, char **err)
225
0
{
226
0
  struct buffer *trash;
227
228
0
  pattern->type = SMP_T_BIN;
229
0
  trash = get_trash_chunk();
230
0
  pattern->len = trash->size;
231
0
  pattern->ptr.str = trash->area;
232
0
  return !!parse_binary(text, &pattern->ptr.str, &pattern->len, err);
233
0
}
234
235
/* Parse a regex. The text is used directly without allocation. */
236
int pat_parse_reg(const char *text, struct pattern *pattern, int mflags, char **err)
237
0
{
238
0
  pattern->ptr.str = (char *)text;
239
0
  return 1;
240
0
}
241
242
/* Parse a range of positive integers delimited by either ':' or '-'. If only
243
 * one integer is read, it is set as both min and max. An operator may be
244
 * specified as the prefix, among this list of 5 :
245
 *
246
 *    0:eq, 1:gt, 2:ge, 3:lt, 4:le
247
 *
248
 * The default operator is "eq". It supports range matching. Ranges are
249
 * rejected for other operators. The operator may be changed at any time.
250
 * The operator is stored in the 'opaque' argument.
251
 *
252
 * If err is non-NULL, an error message will be returned there on errors and
253
 * the caller will have to free it. The function returns zero on error, and
254
 * non-zero on success.
255
 *
256
 */
257
int pat_parse_int(const char *text, struct pattern *pattern, int mflags, char **err)
258
0
{
259
0
  const char *ptr = text;
260
261
0
  pattern->type = SMP_T_SINT;
262
263
  /* Empty string is not valid */
264
0
  if (!*text)
265
0
    goto not_valid_range;
266
267
  /* Search ':' or '-' separator. */
268
0
  while (*ptr != '\0' && *ptr != ':' && *ptr != '-')
269
0
    ptr++;
270
271
  /* If separator not found. */
272
0
  if (!*ptr) {
273
0
    if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0) {
274
0
      memprintf(err, "'%s' is not a number", text);
275
0
      return 0;
276
0
    }
277
0
    pattern->val.range.max = pattern->val.range.min;
278
0
    pattern->val.range.min_set = 1;
279
0
    pattern->val.range.max_set = 1;
280
0
    return 1;
281
0
  }
282
283
  /* If the separator is the first character. */
284
0
  if (ptr == text && *(ptr + 1) != '\0') {
285
0
    if (strl2llrc(ptr + 1, strlen(ptr + 1), &pattern->val.range.max) != 0)
286
0
      goto not_valid_range;
287
288
0
    pattern->val.range.min_set = 0;
289
0
    pattern->val.range.max_set = 1;
290
0
    return 1;
291
0
  }
292
293
  /* If separator is the last character. */
294
0
  if (*(ptr + 1) == '\0') {
295
0
    if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0)
296
0
      goto not_valid_range;
297
298
0
    pattern->val.range.min_set = 1;
299
0
    pattern->val.range.max_set = 0;
300
0
    return 1;
301
0
  }
302
303
  /* Else, parse two numbers. */
304
0
  if (strl2llrc(text, ptr - text, &pattern->val.range.min) != 0)
305
0
    goto not_valid_range;
306
307
0
  if (strl2llrc(ptr + 1, strlen(ptr + 1), &pattern->val.range.max) != 0)
308
0
    goto not_valid_range;
309
310
0
  if (pattern->val.range.min > pattern->val.range.max)
311
0
    goto not_valid_range;
312
313
0
  pattern->val.range.min_set = 1;
314
0
  pattern->val.range.max_set = 1;
315
0
  return 1;
316
317
0
 not_valid_range:
318
0
  memprintf(err, "'%s' is not a valid number range", text);
319
0
  return 0;
320
0
}
321
322
/* Parse a range of positive 2-component versions delimited by either ':' or
323
 * '-'. The version consists in a major and a minor, both of which must be
324
 * smaller than 65536, because internally they will be represented as a 32-bit
325
 * integer.
326
 * If only one version is read, it is set as both min and max. Just like for
327
 * pure integers, an operator may be specified as the prefix, among this list
328
 * of 5 :
329
 *
330
 *    0:eq, 1:gt, 2:ge, 3:lt, 4:le
331
 *
332
 * The default operator is "eq". It supports range matching. Ranges are
333
 * rejected for other operators. The operator may be changed at any time.
334
 * The operator is stored in the 'opaque' argument. This allows constructs
335
 * such as the following one :
336
 *
337
 *    acl obsolete_ssl    ssl_req_proto lt 3
338
 *    acl unsupported_ssl ssl_req_proto gt 3.1
339
 *    acl valid_ssl       ssl_req_proto 3.0-3.1
340
 *
341
 */
342
int pat_parse_dotted_ver(const char *text, struct pattern *pattern, int mflags, char **err)
343
0
{
344
0
  const char *ptr = text;
345
346
0
  pattern->type = SMP_T_SINT;
347
348
  /* Search ':' or '-' separator. */
349
0
  while (*ptr != '\0' && *ptr != ':' && *ptr != '-')
350
0
    ptr++;
351
352
  /* If separator not found. */
353
0
  if (*ptr == '\0' && ptr > text) {
354
0
    if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
355
0
      memprintf(err, "'%s' is not a dotted number", text);
356
0
      return 0;
357
0
    }
358
0
    pattern->val.range.max = pattern->val.range.min;
359
0
    pattern->val.range.min_set = 1;
360
0
    pattern->val.range.max_set = 1;
361
0
    return 1;
362
0
  }
363
364
  /* If the separator is the first character. */
365
0
  if (ptr == text && *(ptr+1) != '\0') {
366
0
    if (strl2llrc_dotted(ptr+1, strlen(ptr+1), &pattern->val.range.max) != 0) {
367
0
      memprintf(err, "'%s' is not a valid dotted number range", text);
368
0
      return 0;
369
0
    }
370
0
    pattern->val.range.min_set = 0;
371
0
    pattern->val.range.max_set = 1;
372
0
    return 1;
373
0
  }
374
375
  /* If separator is the last character. */
376
0
  if (ptr == &text[strlen(text)-1]) {
377
0
    if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
378
0
      memprintf(err, "'%s' is not a valid dotted number range", text);
379
0
      return 0;
380
0
    }
381
0
    pattern->val.range.min_set = 1;
382
0
    pattern->val.range.max_set = 0;
383
0
    return 1;
384
0
  }
385
386
  /* Else, parse two numbers. */
387
0
  if (strl2llrc_dotted(text, ptr-text, &pattern->val.range.min) != 0) {
388
0
    memprintf(err, "'%s' is not a valid dotted number range", text);
389
0
    return 0;
390
0
  }
391
0
  if (strl2llrc_dotted(ptr+1, strlen(ptr+1), &pattern->val.range.max) != 0) {
392
0
    memprintf(err, "'%s' is not a valid dotted number range", text);
393
0
    return 0;
394
0
  }
395
0
  if (pattern->val.range.min > pattern->val.range.max) {
396
0
    memprintf(err, "'%s' is not a valid dotted number range", text);
397
0
    return 0;
398
0
  }
399
0
  pattern->val.range.min_set = 1;
400
0
  pattern->val.range.max_set = 1;
401
0
  return 1;
402
0
}
403
404
/* Parse an IP address and an optional mask in the form addr[/mask].
405
 * The addr may either be an IPv4 address or a hostname. The mask
406
 * may either be a dotted mask or a number of bits. Returns 1 if OK,
407
 * otherwise 0. NOTE: IP address patterns are typed (IPV4/IPV6).
408
 */
409
int pat_parse_ip(const char *text, struct pattern *pattern, int mflags, char **err)
410
0
{
411
0
  if (str2net(text, !(mflags & PAT_MF_NO_DNS) && (global.mode & MODE_STARTING),
412
0
              &pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) {
413
0
    pattern->type = SMP_T_IPV4;
414
0
    return 1;
415
0
  }
416
0
  else if (str62net(text, &pattern->val.ipv6.addr, &pattern->val.ipv6.mask)) {
417
0
    pattern->type = SMP_T_IPV6;
418
0
    return 1;
419
0
  }
420
0
  else {
421
0
    memprintf(err, "'%s' is not a valid IPv4 or IPv6 address", text);
422
0
    return 0;
423
0
  }
424
0
}
425
426
/*
427
 *
428
 * These functions are exported and may be used by any other component.
429
 *
430
 * This function just takes a sample <smp> and checks if this sample matches
431
 * with the pattern <pattern>. This function returns only PAT_MATCH or
432
 * PAT_NOMATCH.
433
 *
434
 */
435
436
/* returns a match when the sample's integer value is non-zero, otherwise returns NULL */
437
struct pattern *pat_match_nothing(struct sample *smp, struct pattern_expr *expr, int fill)
438
0
{
439
0
  if (smp->data.u.sint) {
440
0
    if (fill) {
441
0
      static_pattern.data = NULL;
442
0
      static_pattern.ref = NULL;
443
0
      static_pattern.type = 0;
444
0
      static_pattern.ptr.str = NULL;
445
0
    }
446
0
    return &static_pattern;
447
0
  }
448
0
  else
449
0
    return NULL;
450
0
}
451
452
/* ensure the input sample can be read as a string without knowing its size,
453
 * that is, ensure the terminating null byte is there
454
 *
455
 * The function may fail. Returns 1 on success and 0 on failure
456
 */
457
static inline int pat_match_ensure_str(struct sample *smp)
458
0
{
459
0
  if (smp->data.u.str.data < smp->data.u.str.size) {
460
    /* we have to force a trailing zero on the test pattern and
461
     * the buffer is large enough to accommodate it. If the flag
462
     * CONST is set, duplicate the string
463
     */
464
0
    if (smp->flags & SMP_F_CONST) {
465
0
      if (!smp_dup(smp))
466
0
        return 0;
467
0
    } else
468
0
      smp->data.u.str.area[smp->data.u.str.data] = '\0';
469
0
  }
470
0
  else {
471
    /* Otherwise, the sample is duplicated. A trailing zero
472
     * is automatically added to the string.
473
     */
474
0
    if (!smp_dup(smp))
475
0
      return 0;
476
0
  }
477
0
  return 1;
478
0
}
479
480
/* NB: For two strings to be identical, it is required that their length match */
481
struct pattern *pat_match_str(struct sample *smp, struct pattern_expr *expr, int fill)
482
0
{
483
0
  int icase;
484
0
  struct ebmb_node *node;
485
0
  struct pattern_tree *elt;
486
0
  struct pattern_list *lst;
487
0
  struct pattern *pattern;
488
0
  struct pattern *ret = NULL;
489
0
  struct lru64 *lru = NULL;
490
491
  /* Lookup a string in the expression's pattern tree. */
492
0
  if (!eb_is_empty(&expr->pattern_tree)) {
493
0
    if (!pat_match_ensure_str(smp))
494
0
      return NULL;
495
496
0
    node = ebst_lookup(&expr->pattern_tree, smp->data.u.str.area);
497
498
0
    while (node) {
499
0
      elt = ebmb_entry(node, struct pattern_tree, node);
500
0
      if (elt->ref->gen_id != expr->ref->curr_gen) {
501
0
        node = ebmb_next_dup(node);
502
0
        continue;
503
0
      }
504
0
      if (fill) {
505
0
        static_pattern.data = elt->data;
506
0
        static_pattern.ref = elt->ref;
507
0
        static_pattern.sflags = PAT_SF_TREE;
508
0
        static_pattern.type = SMP_T_STR;
509
0
        static_pattern.ptr.str = (char *)elt->node.key;
510
0
      }
511
0
      return &static_pattern;
512
0
    }
513
0
  }
514
515
  /* look in the list */
516
0
  if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
517
0
    unsigned long long seed = pat_lru_seed ^ (long)expr;
518
519
0
    lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
520
0
        pat_lru_tree, expr, expr->ref->revision);
521
0
    if (lru && lru->domain) {
522
0
      ret = lru->data;
523
0
      return ret;
524
0
    }
525
0
  }
526
527
528
0
  list_for_each_entry(lst, &expr->patterns, list) {
529
0
    pattern = &lst->pat;
530
531
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
532
0
      continue;
533
534
0
    if (pattern->len != smp->data.u.str.data)
535
0
      continue;
536
537
0
    icase = expr->mflags & PAT_MF_IGNORE_CASE;
538
0
    if ((icase && strncasecmp(pattern->ptr.str, smp->data.u.str.area, smp->data.u.str.data) == 0) ||
539
0
        (!icase && strncmp(pattern->ptr.str, smp->data.u.str.area, smp->data.u.str.data) == 0)) {
540
0
      ret = pattern;
541
0
      break;
542
0
    }
543
0
  }
544
545
0
  if (lru)
546
0
    lru64_commit(lru, ret, expr, expr->ref->revision, NULL);
547
548
0
  return ret;
549
0
}
550
551
/* NB: For two binaries buf to be identical, it is required that their lengths match */
552
struct pattern *pat_match_bin(struct sample *smp, struct pattern_expr *expr, int fill)
553
0
{
554
0
  struct pattern_list *lst;
555
0
  struct pattern *pattern;
556
0
  struct pattern *ret = NULL;
557
0
  struct lru64 *lru = NULL;
558
559
0
  if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
560
0
    unsigned long long seed = pat_lru_seed ^ (long)expr;
561
562
0
    lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
563
0
        pat_lru_tree, expr, expr->ref->revision);
564
0
    if (lru && lru->domain) {
565
0
      ret = lru->data;
566
0
      return ret;
567
0
    }
568
0
  }
569
570
0
  list_for_each_entry(lst, &expr->patterns, list) {
571
0
    pattern = &lst->pat;
572
573
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
574
0
      continue;
575
576
0
    if (pattern->len != smp->data.u.str.data)
577
0
      continue;
578
579
0
    if (memcmp(pattern->ptr.str, smp->data.u.str.area, smp->data.u.str.data) == 0) {
580
0
      ret = pattern;
581
0
      break;
582
0
    }
583
0
  }
584
585
0
  if (lru)
586
0
    lru64_commit(lru, ret, expr, expr->ref->revision, NULL);
587
588
0
  return ret;
589
0
}
590
591
/* Executes a regex. It temporarily changes the data to add a trailing zero,
592
 * and restores the previous character when leaving. This function fills
593
 * a matching array.
594
 */
595
struct pattern *pat_match_regm(struct sample *smp, struct pattern_expr *expr, int fill)
596
0
{
597
0
  struct pattern_list *lst;
598
0
  struct pattern *pattern;
599
0
  struct pattern *ret = NULL;
600
601
0
  list_for_each_entry(lst, &expr->patterns, list) {
602
0
    pattern = &lst->pat;
603
604
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
605
0
      continue;
606
607
0
    if (regex_exec_match2(pattern->ptr.reg, smp->data.u.str.area, smp->data.u.str.data,
608
0
                          MAX_MATCH, pmatch, 0)) {
609
0
      ret = pattern;
610
0
      smp->ctx.a[0] = pmatch;
611
0
      break;
612
0
    }
613
0
  }
614
615
0
  return ret;
616
0
}
617
618
/* Executes a regex. It temporarily changes the data to add a trailing zero,
619
 * and restores the previous character when leaving.
620
 */
621
struct pattern *pat_match_reg(struct sample *smp, struct pattern_expr *expr, int fill)
622
0
{
623
0
  struct pattern_list *lst;
624
0
  struct pattern *pattern;
625
0
  struct pattern *ret = NULL;
626
0
  struct lru64 *lru = NULL;
627
628
0
  if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 5) {
629
0
    unsigned long long seed = pat_lru_seed ^ (long)expr;
630
631
0
    lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
632
0
        pat_lru_tree, expr, expr->ref->revision);
633
0
    if (lru && lru->domain) {
634
0
      ret = lru->data;
635
0
      return ret;
636
0
    }
637
0
  }
638
639
0
  list_for_each_entry(lst, &expr->patterns, list) {
640
0
    pattern = &lst->pat;
641
642
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
643
0
      continue;
644
645
0
    if (regex_exec2(pattern->ptr.reg, smp->data.u.str.area, smp->data.u.str.data)) {
646
0
      ret = pattern;
647
0
      break;
648
0
    }
649
0
  }
650
651
0
  if (lru)
652
0
    lru64_commit(lru, ret, expr, expr->ref->revision, NULL);
653
654
0
  return ret;
655
0
}
656
657
/* Checks that the pattern matches the beginning of the tested string. */
658
struct pattern *pat_match_beg(struct sample *smp, struct pattern_expr *expr, int fill)
659
0
{
660
0
  int icase;
661
0
  struct ebmb_node *node;
662
0
  struct pattern_tree *elt;
663
0
  struct pattern_list *lst;
664
0
  struct pattern *pattern;
665
0
  struct pattern *ret = NULL;
666
0
  struct lru64 *lru = NULL;
667
668
  /* Lookup a string in the expression's pattern tree. */
669
0
  if (!eb_is_empty(&expr->pattern_tree)) {
670
0
    if (!pat_match_ensure_str(smp))
671
0
      return NULL;
672
673
0
    node = ebmb_lookup_longest(&expr->pattern_tree,
674
0
             smp->data.u.str.area);
675
676
0
    while (node) {
677
0
      elt = ebmb_entry(node, struct pattern_tree, node);
678
0
      if (elt->ref->gen_id != expr->ref->curr_gen) {
679
0
        node = ebmb_lookup_shorter(node);
680
0
        continue;
681
0
      }
682
0
      if (fill) {
683
0
        static_pattern.data = elt->data;
684
0
        static_pattern.ref = elt->ref;
685
0
        static_pattern.sflags = PAT_SF_TREE;
686
0
        static_pattern.type = SMP_T_STR;
687
0
        static_pattern.ptr.str = (char *)elt->node.key;
688
0
      }
689
0
      return &static_pattern;
690
0
    }
691
0
  }
692
693
  /* look in the list */
694
0
  if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
695
0
    unsigned long long seed = pat_lru_seed ^ (long)expr;
696
697
0
    lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
698
0
        pat_lru_tree, expr, expr->ref->revision);
699
0
    if (lru && lru->domain) {
700
0
      ret = lru->data;
701
0
      return ret;
702
0
    }
703
0
  }
704
705
0
  list_for_each_entry(lst, &expr->patterns, list) {
706
0
    pattern = &lst->pat;
707
708
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
709
0
      continue;
710
711
0
    if (pattern->len > smp->data.u.str.data)
712
0
      continue;
713
714
0
    icase = expr->mflags & PAT_MF_IGNORE_CASE;
715
0
    if ((icase && strncasecmp(pattern->ptr.str, smp->data.u.str.area, pattern->len) != 0) ||
716
0
        (!icase && strncmp(pattern->ptr.str, smp->data.u.str.area, pattern->len) != 0))
717
0
      continue;
718
719
0
    ret = pattern;
720
0
    break;
721
0
  }
722
723
0
  if (lru)
724
0
    lru64_commit(lru, ret, expr, expr->ref->revision, NULL);
725
726
0
  return ret;
727
0
}
728
729
/* Checks that the pattern matches the end of the tested string. */
730
struct pattern *pat_match_end(struct sample *smp, struct pattern_expr *expr, int fill)
731
0
{
732
0
  int icase;
733
0
  struct pattern_list *lst;
734
0
  struct pattern *pattern;
735
0
  struct pattern *ret = NULL;
736
0
  struct lru64 *lru = NULL;
737
738
0
  if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
739
0
    unsigned long long seed = pat_lru_seed ^ (long)expr;
740
741
0
    lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
742
0
        pat_lru_tree, expr, expr->ref->revision);
743
0
    if (lru && lru->domain) {
744
0
      ret = lru->data;
745
0
      return ret;
746
0
    }
747
0
  }
748
749
0
  list_for_each_entry(lst, &expr->patterns, list) {
750
0
    pattern = &lst->pat;
751
752
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
753
0
      continue;
754
755
0
    if (pattern->len > smp->data.u.str.data)
756
0
      continue;
757
758
0
    icase = expr->mflags & PAT_MF_IGNORE_CASE;
759
0
    if ((icase && strncasecmp(pattern->ptr.str, smp->data.u.str.area + smp->data.u.str.data - pattern->len, pattern->len) != 0) ||
760
0
        (!icase && strncmp(pattern->ptr.str, smp->data.u.str.area + smp->data.u.str.data - pattern->len, pattern->len) != 0))
761
0
      continue;
762
763
0
    ret = pattern;
764
0
    break;
765
0
  }
766
767
0
  if (lru)
768
0
    lru64_commit(lru, ret, expr, expr->ref->revision, NULL);
769
770
0
  return ret;
771
0
}
772
773
/* Checks that the pattern is included inside the tested string.
774
 * NB: Suboptimal, should be rewritten using a Boyer-Moore method.
775
 */
776
struct pattern *pat_match_sub(struct sample *smp, struct pattern_expr *expr, int fill)
777
0
{
778
0
  int icase;
779
0
  char *end;
780
0
  char *c;
781
0
  struct pattern_list *lst;
782
0
  struct pattern *pattern;
783
0
  struct pattern *ret = NULL;
784
0
  struct lru64 *lru = NULL;
785
786
0
  if (pat_lru_tree && !LIST_ISEMPTY(&expr->patterns) && expr->ref->entry_cnt >= 20) {
787
0
    unsigned long long seed = pat_lru_seed ^ (long)expr;
788
789
0
    lru = lru64_get(XXH3(smp->data.u.str.area, smp->data.u.str.data, seed),
790
0
        pat_lru_tree, expr, expr->ref->revision);
791
0
    if (lru && lru->domain) {
792
0
      ret = lru->data;
793
0
      return ret;
794
0
    }
795
0
  }
796
797
0
  list_for_each_entry(lst, &expr->patterns, list) {
798
0
    pattern = &lst->pat;
799
800
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
801
0
      continue;
802
803
0
    if (pattern->len > smp->data.u.str.data)
804
0
      continue;
805
806
0
    end = smp->data.u.str.area + smp->data.u.str.data - pattern->len;
807
0
    icase = expr->mflags & PAT_MF_IGNORE_CASE;
808
0
    if (icase) {
809
0
      for (c = smp->data.u.str.area; c <= end; c++) {
810
0
        if (tolower((unsigned char)*c) != tolower((unsigned char)*pattern->ptr.str))
811
0
          continue;
812
0
        if (strncasecmp(pattern->ptr.str, c, pattern->len) == 0) {
813
0
          ret = pattern;
814
0
          goto leave;
815
0
        }
816
0
      }
817
0
    } else {
818
0
      for (c = smp->data.u.str.area; c <= end; c++) {
819
0
        if (*c != *pattern->ptr.str)
820
0
          continue;
821
0
        if (strncmp(pattern->ptr.str, c, pattern->len) == 0) {
822
0
          ret = pattern;
823
0
          goto leave;
824
0
        }
825
0
      }
826
0
    }
827
0
  }
828
0
 leave:
829
0
  if (lru)
830
0
    lru64_commit(lru, ret, expr, expr->ref->revision, NULL);
831
832
0
  return ret;
833
0
}
834
835
/* This one is used by other real functions. It checks that the pattern is
836
 * included inside the tested string, but enclosed between the specified
837
 * delimiters or at the beginning or end of the string. The delimiters are
838
 * provided as an unsigned int made by make_4delim() and match up to 4 different
839
 * delimiters. Delimiters are stripped at the beginning and end of the pattern.
840
 */
841
static int match_word(struct sample *smp, struct pattern *pattern, int mflags, unsigned int delimiters)
842
0
{
843
0
  int may_match, icase;
844
0
  char *c, *end;
845
0
  char *ps;
846
0
  int pl;
847
848
0
  pl = pattern->len;
849
0
  ps = pattern->ptr.str;
850
851
0
  while (pl > 0 && is_delimiter(*ps, delimiters)) {
852
0
    pl--;
853
0
    ps++;
854
0
  }
855
856
0
  while (pl > 0 && is_delimiter(ps[pl - 1], delimiters))
857
0
    pl--;
858
859
0
  if (pl > smp->data.u.str.data)
860
0
    return PAT_NOMATCH;
861
862
0
  may_match = 1;
863
0
  icase = mflags & PAT_MF_IGNORE_CASE;
864
0
  end = smp->data.u.str.area + smp->data.u.str.data - pl;
865
0
  for (c = smp->data.u.str.area; c <= end; c++) {
866
0
    if (is_delimiter(*c, delimiters)) {
867
0
      may_match = 1;
868
0
      continue;
869
0
    }
870
871
0
    if (!may_match)
872
0
      continue;
873
874
0
    if (icase) {
875
0
      if ((tolower((unsigned char)*c) == tolower((unsigned char)*ps)) &&
876
0
          (strncasecmp(ps, c, pl) == 0) &&
877
0
          (c == end || is_delimiter(c[pl], delimiters)))
878
0
        return PAT_MATCH;
879
0
    } else {
880
0
      if ((*c == *ps) &&
881
0
          (strncmp(ps, c, pl) == 0) &&
882
0
          (c == end || is_delimiter(c[pl], delimiters)))
883
0
        return PAT_MATCH;
884
0
    }
885
0
    may_match = 0;
886
0
  }
887
0
  return PAT_NOMATCH;
888
0
}
889
890
/* Checks that the pattern is included inside the tested string, but enclosed
891
 * between the delimiters '?' or '/' or at the beginning or end of the string.
892
 * Delimiters at the beginning or end of the pattern are ignored.
893
 */
894
struct pattern *pat_match_dir(struct sample *smp, struct pattern_expr *expr, int fill)
895
0
{
896
0
  struct pattern_list *lst;
897
0
  struct pattern *pattern;
898
899
0
  list_for_each_entry(lst, &expr->patterns, list) {
900
0
    pattern = &lst->pat;
901
902
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
903
0
      continue;
904
905
0
    if (match_word(smp, pattern, expr->mflags, make_4delim('/', '?', '?', '?')))
906
0
      return pattern;
907
0
  }
908
0
  return NULL;
909
0
}
910
911
/* Checks that the pattern is included inside the tested string, but enclosed
912
 * between the delimiters '/', '?', '.' or ":" or at the beginning or end of
913
 * the string. Delimiters at the beginning or end of the pattern are ignored.
914
 */
915
struct pattern *pat_match_dom(struct sample *smp, struct pattern_expr *expr, int fill)
916
0
{
917
0
  struct pattern_list *lst;
918
0
  struct pattern *pattern;
919
920
0
  list_for_each_entry(lst, &expr->patterns, list) {
921
0
    pattern = &lst->pat;
922
923
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
924
0
      continue;
925
926
0
    if (match_word(smp, pattern, expr->mflags, make_4delim('/', '?', '.', ':')))
927
0
      return pattern;
928
0
  }
929
0
  return NULL;
930
0
}
931
932
/* Checks that the integer in <test> is included between min and max */
933
struct pattern *pat_match_int(struct sample *smp, struct pattern_expr *expr, int fill)
934
0
{
935
0
  struct pattern_list *lst;
936
0
  struct pattern *pattern;
937
938
0
  list_for_each_entry(lst, &expr->patterns, list) {
939
0
    pattern = &lst->pat;
940
941
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
942
0
      continue;
943
944
0
    if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.u.sint) &&
945
0
        (!pattern->val.range.max_set || smp->data.u.sint <= pattern->val.range.max))
946
0
      return pattern;
947
0
  }
948
0
  return NULL;
949
0
}
950
951
/* Checks that the length of the pattern in <test> is included between min and max */
952
struct pattern *pat_match_len(struct sample *smp, struct pattern_expr *expr, int fill)
953
0
{
954
0
  struct pattern_list *lst;
955
0
  struct pattern *pattern;
956
957
0
  list_for_each_entry(lst, &expr->patterns, list) {
958
0
    pattern = &lst->pat;
959
960
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
961
0
      continue;
962
963
0
    if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.u.str.data) &&
964
0
        (!pattern->val.range.max_set || smp->data.u.str.data <= pattern->val.range.max))
965
0
      return pattern;
966
0
  }
967
0
  return NULL;
968
0
}
969
970
/* Performs ipv4 key lookup in <expr> ipv4 tree
971
 * Returns NULL on failure
972
 */
973
static struct pattern *_pat_match_tree_ipv4(struct in_addr *key, struct pattern_expr *expr, int fill)
974
0
{
975
0
  struct ebmb_node *node;
976
0
  struct pattern_tree *elt;
977
978
  /* Lookup an IPv4 address in the expression's pattern tree using
979
   * the longest match method.
980
   */
981
0
  node = ebmb_lookup_longest(&expr->pattern_tree, key);
982
0
  while (node) {
983
0
    elt = ebmb_entry(node, struct pattern_tree, node);
984
0
    if (elt->ref->gen_id != expr->ref->curr_gen) {
985
0
      node = ebmb_lookup_shorter(node);
986
0
      continue;
987
0
    }
988
0
    if (fill) {
989
0
      static_pattern.data = elt->data;
990
0
      static_pattern.ref = elt->ref;
991
0
      static_pattern.sflags = PAT_SF_TREE;
992
0
      static_pattern.type = SMP_T_IPV4;
993
0
      static_pattern.val.ipv4.addr.s_addr = read_u32(elt->node.key);
994
0
      if (!cidr2dotted(elt->node.node.pfx, &static_pattern.val.ipv4.mask))
995
0
        return NULL;
996
0
    }
997
0
    return &static_pattern;
998
0
  }
999
0
  return NULL;
1000
0
}
1001
1002
/* Performs ipv6 key lookup in <expr> ipv6 tree
1003
 * Returns NULL on failure
1004
 */
1005
static struct pattern *_pat_match_tree_ipv6(struct in6_addr *key, struct pattern_expr *expr, int fill)
1006
0
{
1007
0
  struct ebmb_node *node;
1008
0
  struct pattern_tree *elt;
1009
1010
  /* Lookup an IPv6 address in the expression's pattern tree using
1011
   * the longest match method.
1012
   */
1013
0
  node = ebmb_lookup_longest(&expr->pattern_tree_2, key);
1014
0
  while (node) {
1015
0
    elt = ebmb_entry(node, struct pattern_tree, node);
1016
0
    if (elt->ref->gen_id != expr->ref->curr_gen) {
1017
0
      node = ebmb_lookup_shorter(node);
1018
0
      continue;
1019
0
    }
1020
0
    if (fill) {
1021
0
      static_pattern.data = elt->data;
1022
0
      static_pattern.ref = elt->ref;
1023
0
      static_pattern.sflags = PAT_SF_TREE;
1024
0
      static_pattern.type = SMP_T_IPV6;
1025
0
      memcpy(&static_pattern.val.ipv6.addr, elt->node.key, 16);
1026
0
      static_pattern.val.ipv6.mask = elt->node.node.pfx;
1027
0
    }
1028
0
    return &static_pattern;
1029
0
  }
1030
0
  return NULL;
1031
0
}
1032
1033
struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int fill)
1034
0
{
1035
0
  struct in_addr v4;
1036
0
  struct in6_addr v6;
1037
0
  struct pattern_list *lst;
1038
0
  struct pattern *pattern;
1039
1040
  /* The input sample is IPv4. Try to match in the trees. */
1041
0
  if (smp->data.type == SMP_T_IPV4) {
1042
0
    pattern = _pat_match_tree_ipv4(&smp->data.u.ipv4, expr, fill);
1043
0
    if (pattern)
1044
0
      return pattern;
1045
    /* The IPv4 sample don't match the IPv4 tree. Convert the IPv4
1046
     * sample address to IPv6 and try to lookup in the IPv6 tree.
1047
     */
1048
0
    v4tov6(&v6, &smp->data.u.ipv4);
1049
0
    pattern = _pat_match_tree_ipv6(&v6, expr, fill);
1050
0
    if (pattern)
1051
0
      return pattern;
1052
    /* eligible for list lookup using IPv4 address */
1053
0
    v4 = smp->data.u.ipv4;
1054
0
    goto list_lookup;
1055
0
  }
1056
1057
  /* The input sample is IPv6. Try to match in the trees. */
1058
0
  if (smp->data.type == SMP_T_IPV6) {
1059
0
    pattern = _pat_match_tree_ipv6(&smp->data.u.ipv6, expr, fill);
1060
0
    if (pattern)
1061
0
      return pattern;
1062
    /* No match in the IPv6 tree. Try to convert 6 to 4 to lookup in
1063
     * the IPv4 tree
1064
     */
1065
0
    if (v6tov4(&v4, &smp->data.u.ipv6)) {
1066
0
      pattern = _pat_match_tree_ipv4(&v4, expr, fill);
1067
0
      if (pattern)
1068
0
        return pattern;
1069
      /* eligible for list lookup using IPv4 address */
1070
0
      goto list_lookup;
1071
0
    }
1072
0
  }
1073
1074
0
 not_found:
1075
0
  return NULL;
1076
1077
0
 list_lookup:
1078
  /* No match in the trees, but we still have a valid IPv4 address: lookup
1079
   * in the IPv4 list (non-contiguous masks list). This is our last resort
1080
   */
1081
0
  list_for_each_entry(lst, &expr->patterns, list) {
1082
0
    pattern = &lst->pat;
1083
1084
0
    if (pattern->ref->gen_id != expr->ref->curr_gen)
1085
0
      continue;
1086
1087
    /* Check if the input sample match the current pattern. */
1088
0
    if (((v4.s_addr ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0)
1089
0
      return pattern;
1090
0
  }
1091
0
  goto not_found;
1092
0
}
1093
1094
/* finds the pattern holding <list> from list head <head> and deletes it.
1095
 * This is made for use for pattern removal within an expression.
1096
 */
1097
static void pat_unlink_from_head(void **head, void **list)
1098
0
{
1099
0
  while (*head) {
1100
0
    if (*head == list) {
1101
0
      *head = *list;
1102
0
      return;
1103
0
    }
1104
0
    head = *head;
1105
0
  }
1106
0
}
1107
1108
void free_pattern_tree(struct eb_root *root)
1109
0
{
1110
0
  struct eb_node *node, *next;
1111
0
  struct pattern_tree *elt;
1112
1113
0
  node = eb_first(root);
1114
0
  while (node) {
1115
0
    next = eb_next(node);
1116
0
    eb_delete(node);
1117
0
    elt = container_of(node, struct pattern_tree, node);
1118
0
    pat_unlink_from_head(&elt->ref->tree_head, &elt->from_ref);
1119
0
    free(elt->data);
1120
0
    free(elt);
1121
0
    node = next;
1122
0
  }
1123
0
}
1124
1125
void pat_prune_gen(struct pattern_expr *expr)
1126
0
{
1127
0
  struct pattern_list *pat, *tmp;
1128
1129
0
  list_for_each_entry_safe(pat, tmp, &expr->patterns, list) {
1130
0
    LIST_DELETE(&pat->list);
1131
0
    pat_unlink_from_head(&pat->pat.ref->list_head, &pat->from_ref);
1132
0
    if (pat->pat.sflags & PAT_SF_REGFREE)
1133
0
      regex_free(pat->pat.ptr.ptr);
1134
0
    else
1135
0
      free(pat->pat.ptr.ptr);
1136
0
    free(pat->pat.data);
1137
0
    free(pat);
1138
0
  }
1139
1140
0
  free_pattern_tree(&expr->pattern_tree);
1141
0
  free_pattern_tree(&expr->pattern_tree_2);
1142
0
  LIST_INIT(&expr->patterns);
1143
0
  expr->ref->revision = rdtsc();
1144
0
  expr->ref->entry_cnt = 0;
1145
0
}
1146
1147
/*
1148
 *
1149
 * The following functions are used for the pattern indexation
1150
 *
1151
 */
1152
1153
int pat_idx_list_val(struct pattern_expr *expr, struct pattern *pat, char **err)
1154
0
{
1155
0
  struct pattern_list *patl;
1156
1157
  /* allocate pattern */
1158
0
  patl = calloc(1, sizeof(*patl));
1159
0
  if (!patl) {
1160
0
    memprintf(err, "out of memory while indexing pattern");
1161
0
    return 0;
1162
0
  }
1163
1164
  /* duplicate pattern */
1165
0
  memcpy(&patl->pat, pat, sizeof(*pat));
1166
1167
  /* chain pattern in the expression */
1168
0
  LIST_APPEND(&expr->patterns, &patl->list);
1169
0
  patl->expr = expr;
1170
  /* and from the reference */
1171
0
  patl->from_ref = pat->ref->list_head;
1172
0
  pat->ref->list_head = &patl->from_ref;
1173
0
  expr->ref->revision = rdtsc();
1174
0
  expr->ref->entry_cnt++;
1175
1176
  /* that's ok */
1177
0
  return 1;
1178
0
}
1179
1180
int pat_idx_list_ptr(struct pattern_expr *expr, struct pattern *pat, char **err)
1181
0
{
1182
0
  struct pattern_list *patl;
1183
1184
  /* allocate pattern */
1185
0
  patl = calloc(1, sizeof(*patl));
1186
0
  if (!patl) {
1187
0
    memprintf(err, "out of memory while indexing pattern");
1188
0
    return 0;
1189
0
  }
1190
1191
  /* duplicate pattern */
1192
0
  memcpy(&patl->pat, pat, sizeof(*pat));
1193
0
  patl->pat.ptr.ptr = malloc(patl->pat.len);
1194
0
  if (!patl->pat.ptr.ptr) {
1195
0
    free(patl);
1196
0
    memprintf(err, "out of memory while indexing pattern");
1197
0
    return 0;
1198
0
  }
1199
0
  memcpy(patl->pat.ptr.ptr, pat->ptr.ptr, pat->len);
1200
1201
  /* chain pattern in the expression */
1202
0
  LIST_APPEND(&expr->patterns, &patl->list);
1203
0
  patl->expr = expr;
1204
  /* and from the reference */
1205
0
  patl->from_ref = pat->ref->list_head;
1206
0
  pat->ref->list_head = &patl->from_ref;
1207
0
  expr->ref->revision = rdtsc();
1208
0
  expr->ref->entry_cnt++;
1209
1210
  /* that's ok */
1211
0
  return 1;
1212
0
}
1213
1214
int pat_idx_list_str(struct pattern_expr *expr, struct pattern *pat, char **err)
1215
0
{
1216
0
  struct pattern_list *patl;
1217
1218
  /* allocate pattern */
1219
0
  patl = calloc(1, sizeof(*patl));
1220
0
  if (!patl) {
1221
0
    memprintf(err, "out of memory while indexing pattern");
1222
0
    return 0;
1223
0
  }
1224
1225
  /* duplicate pattern */
1226
0
  memcpy(&patl->pat, pat, sizeof(*pat));
1227
0
  patl->pat.ptr.str = malloc(patl->pat.len + 1);
1228
0
  if (!patl->pat.ptr.str) {
1229
0
    free(patl);
1230
0
    memprintf(err, "out of memory while indexing pattern");
1231
0
    return 0;
1232
0
  }
1233
0
  memcpy(patl->pat.ptr.ptr, pat->ptr.ptr, pat->len);
1234
0
  patl->pat.ptr.str[patl->pat.len] = '\0';
1235
1236
  /* chain pattern in the expression */
1237
0
  LIST_APPEND(&expr->patterns, &patl->list);
1238
0
  patl->expr = expr;
1239
  /* and from the reference */
1240
0
  patl->from_ref = pat->ref->list_head;
1241
0
  pat->ref->list_head = &patl->from_ref;
1242
0
  expr->ref->revision = rdtsc();
1243
0
  expr->ref->entry_cnt++;
1244
1245
  /* that's ok */
1246
0
  return 1;
1247
0
}
1248
1249
int pat_idx_list_reg_cap(struct pattern_expr *expr, struct pattern *pat, int cap, char **err)
1250
0
{
1251
0
  struct pattern_list *patl;
1252
1253
  /* allocate pattern */
1254
0
  patl = calloc(1, sizeof(*patl));
1255
0
  if (!patl) {
1256
0
    memprintf(err, "out of memory while indexing pattern");
1257
0
    return 0;
1258
0
  }
1259
1260
  /* duplicate pattern */
1261
0
  memcpy(&patl->pat, pat, sizeof(*pat));
1262
1263
  /* compile regex */
1264
0
  patl->pat.sflags |= PAT_SF_REGFREE;
1265
0
  if (!(patl->pat.ptr.reg = regex_comp(pat->ptr.str, !(expr->mflags & PAT_MF_IGNORE_CASE),
1266
0
                                       cap, err))) {
1267
0
    free(patl);
1268
0
    return 0;
1269
0
  }
1270
1271
  /* chain pattern in the expression */
1272
0
  LIST_APPEND(&expr->patterns, &patl->list);
1273
0
  patl->expr = expr;
1274
  /* and from the reference */
1275
0
  patl->from_ref = pat->ref->list_head;
1276
0
  pat->ref->list_head = &patl->from_ref;
1277
0
  expr->ref->revision = rdtsc();
1278
0
  expr->ref->entry_cnt++;
1279
1280
  /* that's ok */
1281
0
  return 1;
1282
0
}
1283
1284
int pat_idx_list_reg(struct pattern_expr *expr, struct pattern *pat, char **err)
1285
0
{
1286
0
  return pat_idx_list_reg_cap(expr, pat, 0, err);
1287
0
}
1288
1289
int pat_idx_list_regm(struct pattern_expr *expr, struct pattern *pat, char **err)
1290
0
{
1291
0
  return pat_idx_list_reg_cap(expr, pat, 1, err);
1292
0
}
1293
1294
int pat_idx_tree_ip(struct pattern_expr *expr, struct pattern *pat, char **err)
1295
0
{
1296
0
  unsigned int mask;
1297
0
  struct pattern_tree *node;
1298
1299
  /* Only IPv4 can be indexed */
1300
0
  if (pat->type == SMP_T_IPV4) {
1301
    /* in IPv4 case, check if the mask is contiguous so that we can
1302
     * insert the network into the tree. A continuous mask has only
1303
     * ones on the left. This means that this mask + its lower bit
1304
     * added once again is null.
1305
     */
1306
0
    mask = ntohl(pat->val.ipv4.mask.s_addr);
1307
0
    if (mask + (mask & -mask) == 0) {
1308
0
      mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
1309
1310
      /* node memory allocation */
1311
0
      node = calloc(1, sizeof(*node) + 4);
1312
0
      if (!node) {
1313
0
        memprintf(err, "out of memory while loading pattern");
1314
0
        return 0;
1315
0
      }
1316
1317
      /* copy the pointer to sample associated to this node */
1318
0
      node->data = pat->data;
1319
0
      node->ref = pat->ref;
1320
1321
      /* FIXME: insert <addr>/<mask> into the tree here */
1322
0
      memcpy(node->node.key, &pat->val.ipv4.addr, 4); /* network byte order */
1323
0
      node->node.node.pfx = mask;
1324
1325
      /* Insert the entry. */
1326
0
      ebmb_insert_prefix(&expr->pattern_tree, &node->node, 4);
1327
1328
0
      node->expr = expr;
1329
0
      node->from_ref = pat->ref->tree_head;
1330
0
      pat->ref->tree_head = &node->from_ref;
1331
0
      expr->ref->revision = rdtsc();
1332
0
      expr->ref->entry_cnt++;
1333
1334
      /* that's ok */
1335
0
      return 1;
1336
0
    }
1337
0
    else {
1338
      /* If the mask is not contiguous, just add the pattern to the list */
1339
0
      return pat_idx_list_val(expr, pat, err);
1340
0
    }
1341
0
  }
1342
0
  else if (pat->type == SMP_T_IPV6) {
1343
    /* IPv6 also can be indexed */
1344
0
    node = calloc(1, sizeof(*node) + 16);
1345
0
    if (!node) {
1346
0
      memprintf(err, "out of memory while loading pattern");
1347
0
      return 0;
1348
0
    }
1349
1350
    /* copy the pointer to sample associated to this node */
1351
0
    node->data = pat->data;
1352
0
    node->ref = pat->ref;
1353
1354
    /* FIXME: insert <addr>/<mask> into the tree here */
1355
0
    memcpy(node->node.key, &pat->val.ipv6.addr, 16); /* network byte order */
1356
0
    node->node.node.pfx = pat->val.ipv6.mask;
1357
1358
    /* Insert the entry. */
1359
0
    ebmb_insert_prefix(&expr->pattern_tree_2, &node->node, 16);
1360
1361
0
    node->expr = expr;
1362
0
    node->from_ref = pat->ref->tree_head;
1363
0
    pat->ref->tree_head = &node->from_ref;
1364
0
    expr->ref->revision = rdtsc();
1365
0
    expr->ref->entry_cnt++;
1366
1367
    /* that's ok */
1368
0
    return 1;
1369
0
  }
1370
1371
0
  return 0;
1372
0
}
1373
1374
int pat_idx_tree_str(struct pattern_expr *expr, struct pattern *pat, char **err)
1375
0
{
1376
0
  int len;
1377
0
  struct pattern_tree *node;
1378
1379
  /* Only string can be indexed */
1380
0
  if (pat->type != SMP_T_STR) {
1381
0
    memprintf(err, "internal error: string expected, but the type is '%s'",
1382
0
              smp_to_type[pat->type]);
1383
0
    return 0;
1384
0
  }
1385
1386
  /* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
1387
0
  if (expr->mflags & PAT_MF_IGNORE_CASE)
1388
0
    return pat_idx_list_str(expr, pat, err);
1389
1390
  /* Process the key len */
1391
0
  len = strlen(pat->ptr.str) + 1;
1392
1393
  /* node memory allocation */
1394
0
  node = calloc(1, sizeof(*node) + len);
1395
0
  if (!node) {
1396
0
    memprintf(err, "out of memory while loading pattern");
1397
0
    return 0;
1398
0
  }
1399
1400
  /* copy the pointer to sample associated to this node */
1401
0
  node->data = pat->data;
1402
0
  node->ref = pat->ref;
1403
1404
  /* copy the string */
1405
0
  memcpy(node->node.key, pat->ptr.str, len);
1406
1407
  /* index the new node */
1408
0
  ebst_insert(&expr->pattern_tree, &node->node);
1409
1410
0
  node->expr = expr;
1411
0
  node->from_ref = pat->ref->tree_head;
1412
0
  pat->ref->tree_head = &node->from_ref;
1413
0
  expr->ref->revision = rdtsc();
1414
0
  expr->ref->entry_cnt++;
1415
1416
  /* that's ok */
1417
0
  return 1;
1418
0
}
1419
1420
int pat_idx_tree_pfx(struct pattern_expr *expr, struct pattern *pat, char **err)
1421
0
{
1422
0
  int len;
1423
0
  struct pattern_tree *node;
1424
1425
  /* Only string can be indexed */
1426
0
  if (pat->type != SMP_T_STR) {
1427
0
    memprintf(err, "internal error: string expected, but the type is '%s'",
1428
0
              smp_to_type[pat->type]);
1429
0
    return 0;
1430
0
  }
1431
1432
  /* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
1433
0
  if (expr->mflags & PAT_MF_IGNORE_CASE)
1434
0
    return pat_idx_list_str(expr, pat, err);
1435
1436
  /* Process the key len */
1437
0
  len = strlen(pat->ptr.str);
1438
1439
  /* node memory allocation */
1440
0
  node = calloc(1, sizeof(*node) + len + 1);
1441
0
  if (!node) {
1442
0
    memprintf(err, "out of memory while loading pattern");
1443
0
    return 0;
1444
0
  }
1445
1446
  /* copy the pointer to sample associated to this node */
1447
0
  node->data = pat->data;
1448
0
  node->ref = pat->ref;
1449
1450
  /* copy the string and the trailing zero */
1451
0
  memcpy(node->node.key, pat->ptr.str, len + 1);
1452
0
  node->node.node.pfx = len * 8;
1453
1454
  /* index the new node */
1455
0
  ebmb_insert_prefix(&expr->pattern_tree, &node->node, len);
1456
1457
0
  node->expr = expr;
1458
0
  node->from_ref = pat->ref->tree_head;
1459
0
  pat->ref->tree_head = &node->from_ref;
1460
0
  expr->ref->revision = rdtsc();
1461
0
  expr->ref->entry_cnt++;
1462
1463
  /* that's ok */
1464
0
  return 1;
1465
0
}
1466
1467
/* Deletes all patterns from reference <elt>. Note that all of their
1468
 * expressions must be locked, and the pattern lock must be held as well.
1469
 */
1470
void pat_delete_gen(struct pat_ref *ref, struct pat_ref_elt *elt)
1471
0
{
1472
0
  struct pattern_tree *tree;
1473
0
  struct pattern_list *pat;
1474
0
  void **node;
1475
1476
  /* delete all known tree nodes. They are all allocated inline */
1477
0
  for (node = elt->tree_head; node;) {
1478
0
    tree = container_of(node, struct pattern_tree, from_ref);
1479
0
    node = *node;
1480
0
    BUG_ON(tree->ref != elt);
1481
1482
0
    ebmb_delete(&tree->node);
1483
0
    free(tree->data);
1484
0
    free(tree);
1485
0
  }
1486
1487
  /* delete all list nodes and free their pattern entries (str/reg) */
1488
0
  for (node = elt->list_head; node;) {
1489
0
    pat = container_of(node, struct pattern_list, from_ref);
1490
0
    node = *node;
1491
0
    BUG_ON(pat->pat.ref != elt);
1492
1493
    /* Delete and free entry. */
1494
0
    LIST_DELETE(&pat->list);
1495
0
    if (pat->pat.sflags & PAT_SF_REGFREE)
1496
0
      regex_free(pat->pat.ptr.reg);
1497
0
    else
1498
0
      free(pat->pat.ptr.ptr);
1499
0
    free(pat->pat.data);
1500
0
    free(pat);
1501
0
  }
1502
1503
  /* update revision number to refresh the cache */
1504
0
  ref->revision = rdtsc();
1505
0
  ref->entry_cnt--;
1506
0
  elt->tree_head = NULL;
1507
0
  elt->list_head = NULL;
1508
0
}
1509
1510
void pattern_init_expr(struct pattern_expr *expr)
1511
0
{
1512
0
  LIST_INIT(&expr->patterns);
1513
0
  expr->pattern_tree = EB_ROOT;
1514
0
  expr->pattern_tree_2 = EB_ROOT;
1515
0
}
1516
1517
void pattern_init_head(struct pattern_head *head)
1518
0
{
1519
0
  LIST_INIT(&head->head);
1520
0
}
1521
1522
/* The following functions are relative to the management of the reference
1523
 * lists. These lists are used to store the original pattern and associated
1524
 * value as string form.
1525
 *
1526
 * This is used with modifiable ACL and MAPS
1527
 *
1528
 * The pattern reference are stored with two identifiers: the unique_id and
1529
 * the reference.
1530
 *
1531
 * The reference identify a file. Each file with the same name point to the
1532
 * same reference. We can register many times one file. If the file is modified,
1533
 * all his dependencies are also modified. The reference can be used with map or
1534
 * acl.
1535
 *
1536
 * The unique_id identify inline acl. The unique id is unique for each acl.
1537
 * You cannot force the same id in the configuration file, because this repoort
1538
 * an error.
1539
 *
1540
 * A particular case appears if the filename is a number. In this case, the
1541
 * unique_id is set with the number represented by the filename and the
1542
 * reference is also set. This method prevent double unique_id.
1543
 *
1544
 */
1545
1546
/* This function looks up a reference by name. If the reference is found, a
1547
 * pointer to the struct pat_ref is returned, otherwise NULL is returned.
1548
 */
1549
struct pat_ref *pat_ref_lookup(const char *reference)
1550
0
{
1551
0
  struct pat_ref *ref;
1552
1553
  /* Skip file@ or opt@ prefix, it is the default case. Can be mixed with ref omitting the prefix */
1554
0
  if (strlen(reference) > 5 && strncmp(reference, "file@", 5) == 0)
1555
0
    reference += 5;
1556
0
  else if (strlen(reference) > 4 && strncmp(reference, "opt@", 4) == 0)
1557
0
    reference += 4;
1558
1559
0
  list_for_each_entry(ref, &pattern_reference, list)
1560
0
    if (ref->reference && strcmp(reference, ref->reference) == 0)
1561
0
      return ref;
1562
0
  return NULL;
1563
0
}
1564
1565
/* This function looks up a reference's unique id. If the reference is found, a
1566
 * pointer to the struct pat_ref is returned, otherwise NULL is returned.
1567
 */
1568
struct pat_ref *pat_ref_lookupid(int unique_id)
1569
0
{
1570
0
  struct pat_ref *ref;
1571
1572
0
  list_for_each_entry(ref, &pattern_reference, list)
1573
0
    if (ref->unique_id == unique_id)
1574
0
      return ref;
1575
0
  return NULL;
1576
0
}
1577
1578
/* This function removes from the pattern reference <ref> all the patterns
1579
 * attached to the reference element <elt>, and the element itself. The
1580
 * reference must be locked.
1581
 */
1582
void pat_ref_delete_by_ptr(struct pat_ref *ref, struct pat_ref_elt *elt)
1583
0
{
1584
0
  struct pat_ref_gen *gen;
1585
0
  struct pattern_expr *expr;
1586
0
  struct bref *bref, *back;
1587
1588
0
  gen = pat_ref_gen_get(ref, elt->gen_id);
1589
0
  BUG_ON(!gen);
1590
1591
  /*
1592
   * we have to unlink all watchers from this reference pattern. We must
1593
   * not relink them if this elt was the last one in the list.
1594
   */
1595
0
  list_for_each_entry_safe(bref, back, &elt->back_refs, users) {
1596
0
    LIST_DELETE(&bref->users);
1597
0
    LIST_INIT(&bref->users);
1598
0
    if (elt->list.n != &gen->head)
1599
0
      LIST_APPEND(&LIST_ELEM(elt->list.n, typeof(elt), list)->back_refs, &bref->users);
1600
0
    bref->ref = elt->list.n;
1601
0
  }
1602
1603
  /* delete all entries from all expressions for this pattern */
1604
0
  list_for_each_entry(expr, &ref->pat, list)
1605
0
    HA_RWLOCK_WRLOCK(PATEXP_LOCK, &expr->lock);
1606
1607
0
  pat_delete_gen(ref, elt);
1608
1609
0
  list_for_each_entry(expr, &ref->pat, list)
1610
0
    HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
1611
1612
0
  LIST_DELETE(&elt->list);
1613
0
  cebs_item_delete(&gen->elt_root, node, pattern, elt);
1614
0
  free(elt->sample);
1615
0
  free(elt);
1616
0
  HA_ATOMIC_INC(&patterns_freed);
1617
0
}
1618
1619
/* This function removes the pattern matching the pointer <refelt> from
1620
 * the reference and from each expr member of this reference. This function
1621
 * returns 1 if the entry was found and deleted, otherwise zero.
1622
 *
1623
 * <refelt> is user input: it is provided as an ID and should never be
1624
 * dereferenced without making sure that it is valid.
1625
 */
1626
int pat_ref_delete_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt)
1627
0
{
1628
0
  struct pat_ref_gen *gen;
1629
0
  struct pat_ref_elt *elt, *safe;
1630
1631
  /* delete pattern from reference */
1632
0
  pat_ref_gen_foreach(gen, ref) {
1633
0
    list_for_each_entry_safe(elt, safe, &gen->head, list) {
1634
0
      if (elt == refelt) {
1635
0
        event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_DEL, NULL);
1636
0
        pat_ref_delete_by_ptr(ref, elt);
1637
0
        return 1;
1638
0
      }
1639
0
    }
1640
0
  }
1641
0
  return 0;
1642
0
}
1643
1644
/* Create a new generation object.
1645
 *
1646
 * Returns NULL in case of memory allocation failure.
1647
 */
1648
struct pat_ref_gen *pat_ref_gen_new(struct pat_ref *ref, unsigned int gen_id)
1649
0
{
1650
0
  struct pat_ref_gen *gen, *old;
1651
1652
0
  gen = malloc(sizeof(struct pat_ref_gen));
1653
0
  if (!gen)
1654
0
    return NULL;
1655
1656
0
  LIST_INIT(&gen->head);
1657
0
  ceb_init_root(&gen->elt_root);
1658
0
  gen->gen_id = gen_id;
1659
1660
0
  old = cebu32_item_insert(&ref->gen_root, gen_node, gen_id, gen);
1661
0
  BUG_ON(old != gen, "Generation ID already exists");
1662
1663
0
  return gen;
1664
0
}
1665
1666
/* Find the generation <gen_id> in the pattern reference <ref>.
1667
 *
1668
 * Returns NULL if the generation cannot be found.
1669
 */
1670
struct pat_ref_gen *pat_ref_gen_get(struct pat_ref *ref, unsigned int gen_id)
1671
0
{
1672
0
  struct pat_ref_gen *gen;
1673
1674
  /* We optimistically try to use the cached generation if it's the current one. */
1675
0
  if (likely(gen_id == ref->curr_gen && gen_id == ref->cached_gen.id && ref->cached_gen.data))
1676
0
    return ref->cached_gen.data;
1677
1678
0
  gen = cebu32_item_lookup(&ref->gen_root, gen_node, gen_id, gen_id, struct pat_ref_gen);
1679
0
  if (unlikely(!gen))
1680
0
    return NULL;
1681
1682
0
  if (gen_id == ref->curr_gen) {
1683
0
    ref->cached_gen.id = gen_id;
1684
0
    ref->cached_gen.data = gen;
1685
0
  }
1686
0
  return gen;
1687
0
}
1688
1689
/* This function removes all elements belonging to <gen_id> and matching <key>
1690
 * from the reference <ref>.
1691
 * This function returns 1 if the deletion is done and returns 0 if
1692
 * the entry is not found.
1693
 */
1694
int pat_ref_gen_delete(struct pat_ref *ref, unsigned int gen_id, const char *key)
1695
0
{
1696
0
  struct pat_ref_gen *gen;
1697
0
  struct pat_ref_elt *elt;
1698
1699
0
  gen = pat_ref_gen_get(ref, gen_id);
1700
0
  if (!gen)
1701
0
    return 0;
1702
1703
  /* delete pattern from reference */
1704
0
  elt = cebs_item_lookup(&gen->elt_root, node, pattern, key, struct pat_ref_elt);
1705
0
  if (!elt)
1706
0
    return 0;
1707
1708
0
  pat_ref_delete_by_ptr(ref, elt);
1709
0
  event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_DEL, NULL);
1710
0
  return 1;
1711
0
}
1712
1713
/* This function removes all patterns matching <key> from the reference
1714
 * and from each expr member of the reference. This function returns 1
1715
 * if the deletion is done and returns 0 is the entry is not found.
1716
 */
1717
int pat_ref_delete(struct pat_ref *ref, const char *key)
1718
0
{
1719
0
  return pat_ref_gen_delete(ref, ref->curr_gen, key);
1720
0
}
1721
1722
/*
1723
 * find and return an element <elt> belonging to <gen_id> and matching <key> in a
1724
 * reference <ref> return NULL if not found
1725
 */
1726
struct pat_ref_elt *pat_ref_gen_find_elt(struct pat_ref *ref, unsigned int gen_id, const char *key)
1727
0
{
1728
0
  struct pat_ref_gen *gen;
1729
1730
0
  gen = pat_ref_gen_get(ref, gen_id);
1731
0
  if (!gen)
1732
0
    return NULL;
1733
0
  return cebs_item_lookup(&gen->elt_root, node, pattern, key, struct pat_ref_elt);
1734
0
}
1735
1736
/*
1737
 * find and return an element <elt> matching <key> in a reference <ref>
1738
 * return NULL if not found
1739
 */
1740
struct pat_ref_elt *pat_ref_find_elt(struct pat_ref *ref, const char *key)
1741
0
{
1742
0
  return pat_ref_gen_find_elt(ref, ref->curr_gen, key);
1743
0
}
1744
1745
1746
/* This function modifies the sample of pat_ref_elt <elt> in all expressions
1747
 * found under <ref> to become <value>. It is assumed that the caller has
1748
 * already verified that <elt> belongs to <ref>.
1749
 */
1750
static inline int pat_ref_set_elt(struct pat_ref *ref, struct pat_ref_elt *elt,
1751
                                  const char *value, char **err)
1752
0
{
1753
0
  struct pattern_expr *expr;
1754
0
  struct sample_data **data;
1755
0
  char *sample;
1756
0
  struct sample_data test;
1757
0
  struct pattern_tree *tree;
1758
0
  struct pattern_list *pat;
1759
0
  void **node;
1760
1761
1762
  /* Try all needed converters. */
1763
0
  list_for_each_entry(expr, &ref->pat, list) {
1764
0
    if (!expr->pat_head->parse_smp)
1765
0
      continue;
1766
1767
0
    if (!expr->pat_head->parse_smp(value, &test)) {
1768
0
      memprintf(err, "unable to parse '%s'", value);
1769
0
      return 0;
1770
0
    }
1771
0
  }
1772
1773
  /* Modify pattern from reference. */
1774
0
  sample = strdup(value);
1775
0
  if (!sample) {
1776
0
    memprintf(err, "out of memory error");
1777
0
    return 0;
1778
0
  }
1779
  /* Load sample in each reference. All the conversions are tested
1780
   * below, normally these calls don't fail.
1781
   */
1782
0
  for (node = elt->tree_head; node;) {
1783
0
    tree = container_of(node, struct pattern_tree, from_ref);
1784
0
    node = *node;
1785
0
    BUG_ON(tree->ref != elt);
1786
0
    expr = tree->expr;
1787
0
    if (!expr->pat_head->parse_smp)
1788
0
      continue;
1789
1790
0
    data = &tree->data;
1791
0
    if (data && *data) {
1792
0
      HA_RWLOCK_WRLOCK(PATEXP_LOCK, &expr->lock);
1793
0
      if (!expr->pat_head->parse_smp(sample, *data))
1794
0
        *data = NULL;
1795
0
      HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
1796
0
    }
1797
0
  }
1798
1799
0
  for (node = elt->list_head; node;) {
1800
0
    pat = container_of(node, struct pattern_list, from_ref);
1801
0
    node = *node;
1802
0
    BUG_ON(pat->pat.ref != elt);
1803
0
    expr = pat->expr;
1804
0
    if (!expr->pat_head->parse_smp)
1805
0
      continue;
1806
1807
0
    data = &pat->pat.data;
1808
0
    if (data && *data) {
1809
0
      HA_RWLOCK_WRLOCK(PATEXP_LOCK, &expr->lock);
1810
0
      if (!expr->pat_head->parse_smp(sample, *data))
1811
0
        *data = NULL;
1812
0
      HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
1813
0
    }
1814
0
  }
1815
1816
  /* free old sample only when all exprs are updated */
1817
0
  free(elt->sample);
1818
0
  elt->sample = sample;
1819
1820
1821
0
  return 1;
1822
0
}
1823
1824
/* This function modifies the sample of pat_ref_elt <refelt> in all expressions
1825
 * found under <ref> to become <value>, after checking that <refelt> really
1826
 * belongs to <ref>.
1827
 *
1828
 * <refelt> is user input: it is provided as an ID and should never be
1829
 * dereferenced without making sure that it is valid.
1830
 */
1831
int pat_ref_set_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt, const char *value, char **err)
1832
0
{
1833
0
  struct pat_ref_gen *gen;
1834
0
  struct pat_ref_elt *elt;
1835
1836
  /* Look for pattern in the reference. */
1837
0
  pat_ref_gen_foreach(gen, ref) {
1838
0
    list_for_each_entry(elt, &gen->head, list) {
1839
0
      if (elt == refelt) {
1840
0
        if (!pat_ref_set_elt(ref, elt, value, err))
1841
0
          return 0;
1842
0
        return 1;
1843
0
      }
1844
0
    }
1845
0
  }
1846
1847
0
  memprintf(err, "key or pattern not found");
1848
0
  return 0;
1849
0
}
1850
1851
static int pat_ref_set_from_elt(struct pat_ref *ref, struct pat_ref_elt *elt, const char *value, char **err)
1852
0
{
1853
0
  struct pat_ref_gen *gen;
1854
0
  struct pat_ref_elt *elt2;
1855
0
  int found = 0, publish = 0;
1856
1857
0
  if (elt) {
1858
0
    if (elt->gen_id == ref->curr_gen)
1859
0
      publish = 1;
1860
0
    gen = pat_ref_gen_get(ref, elt->gen_id);
1861
0
    BUG_ON(!gen);
1862
1863
0
    for (; elt; elt = elt2) {
1864
0
      char *tmp_err = NULL;
1865
1866
0
      elt2 = cebs_item_next_dup(&gen->elt_root, node, pattern, elt);
1867
1868
0
      if (!pat_ref_set_elt(ref, elt, value, &tmp_err)) {
1869
0
        if (err)
1870
0
          *err = tmp_err;
1871
0
        else
1872
0
          ha_free(&tmp_err);
1873
0
        return 0;
1874
0
      }
1875
0
      found = 1;
1876
0
    }
1877
0
  }
1878
1879
0
  if (!found) {
1880
0
    memprintf(err, "entry not found");
1881
0
    return 0;
1882
0
  }
1883
1884
0
  if (publish)
1885
0
    event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_SET, NULL);
1886
1887
0
  return 1;
1888
0
}
1889
1890
/* modifies to <value> the sample for <elt> and all its duplicates */
1891
int pat_ref_set_elt_duplicate(struct pat_ref *ref, struct pat_ref_elt *elt, const char *value,
1892
                              char **err)
1893
0
{
1894
0
  return pat_ref_set_from_elt(ref, elt, value, err);
1895
0
}
1896
1897
/* This function modifies to <value> the sample of all patterns matching <key>
1898
 * and belonging to <gen_id> under <ref>.
1899
 */
1900
int pat_ref_gen_set(struct pat_ref *ref, unsigned int gen_id,
1901
                    const char *key, const char *value, char **err)
1902
0
{
1903
0
  struct pat_ref_gen *gen;
1904
0
  struct pat_ref_elt *elt;
1905
1906
  /* Look for pattern in the reference. */
1907
0
  gen = pat_ref_gen_get(ref, gen_id);
1908
0
  if (gen)
1909
0
    elt = cebs_item_lookup(&gen->elt_root, node, pattern, key, struct pat_ref_elt);
1910
0
  else
1911
0
    elt = NULL;
1912
0
  return pat_ref_set_from_elt(ref, elt, value, err);
1913
0
}
1914
1915
/* This function modifies to <value> the sample of all patterns matching <key>
1916
 * under <ref>.
1917
 */
1918
int pat_ref_set(struct pat_ref *ref, const char *key, const char *value, char **err)
1919
0
{
1920
0
  return pat_ref_gen_set(ref, ref->curr_gen, key, value, err);
1921
0
}
1922
1923
/* helper function to create and initialize a generic pat_ref struct
1924
 *
1925
 * Returns the new struct on success and NULL on failure (memory allocation
1926
 * error)
1927
 */
1928
static struct pat_ref *_pat_ref_new(const char *display, unsigned int flags)
1929
0
{
1930
0
  struct pat_ref *ref;
1931
1932
0
  ref = malloc(sizeof(*ref));
1933
0
  if (!ref)
1934
0
    return NULL;
1935
1936
  /* don't forget to explicitly initialize all pat_ref struct members */
1937
1938
0
  if (display) {
1939
0
    ref->display = strdup(display);
1940
0
    if (!ref->display) {
1941
0
      free(ref);
1942
0
      return NULL;
1943
0
    }
1944
0
  }
1945
1946
0
  ref->reference = NULL;
1947
0
  ref->flags = flags;
1948
0
  ref->curr_gen = 0;
1949
0
        ref->next_gen = 0;
1950
0
  ref->unique_id = -1;
1951
0
  ref->revision = 0;
1952
0
  ref->entry_cnt = 0;
1953
0
  ceb_init_root(&ref->gen_root);
1954
0
  ref->cached_gen.id = ref->curr_gen;
1955
0
  ref->cached_gen.data = NULL;
1956
0
  LIST_INIT(&ref->pat);
1957
0
  HA_RWLOCK_INIT(&ref->lock);
1958
0
  event_hdl_sub_list_init(&ref->e_subs);
1959
1960
0
  return ref;
1961
0
}
1962
1963
/* helper func to properly de-initialize and free pat_ref struct */
1964
static void pat_ref_free(struct pat_ref *ref)
1965
0
{
1966
0
  ha_free(&ref->reference);
1967
0
  ha_free(&ref->display);
1968
0
  event_hdl_sub_list_destroy(&ref->e_subs);
1969
0
  free(ref);
1970
0
}
1971
1972
/* This function creates a new reference. <ref> is the reference name.
1973
 * <flags> are PAT_REF_*. /!\ The reference is not checked, and must
1974
 * be unique. The user must check the reference with "pat_ref_lookup()"
1975
 * before calling this function. If the function fails, it returns NULL,
1976
 * otherwise it returns the new struct pat_ref.
1977
 */
1978
struct pat_ref *pat_ref_new(const char *reference, const char *display, unsigned int flags)
1979
0
{
1980
0
  struct pat_ref *ref;
1981
1982
0
  ref = _pat_ref_new(display, flags);
1983
0
  if (!ref)
1984
0
    return NULL;
1985
1986
0
  if (strlen(reference) > 5 && strncmp(reference, "virt@", 5) == 0)
1987
0
    ref->flags |= PAT_REF_ID;
1988
0
  else if (strlen(reference) > 4 && strncmp(reference, "opt@", 4) == 0) {
1989
0
    ref->flags |= (PAT_REF_ID|PAT_REF_FILE); // Will be decided later
1990
0
    reference += 4;
1991
0
  }
1992
0
  else {
1993
    /* A file by default */
1994
0
    ref->flags |= PAT_REF_FILE;
1995
    /* Skip file@ prefix to be mixed with ref omitting the prefix */
1996
0
    if (strlen(reference) > 5 && strncmp(reference, "file@", 5) == 0)
1997
0
      reference += 5;
1998
0
  }
1999
2000
2001
0
  ref->reference = strdup(reference);
2002
0
  if (!ref->reference) {
2003
0
    pat_ref_free(ref);
2004
0
    return NULL;
2005
0
  }
2006
2007
0
  LIST_APPEND(&pattern_reference, &ref->list);
2008
0
  return ref;
2009
0
}
2010
2011
/* This function creates a new reference. <unique_id> is the unique id. If
2012
 * the value of <unique_id> is -1, the unique id is calculated later.
2013
 * <flags> are PAT_REF_*. /!\ The reference is not checked, and must
2014
 * be unique. The user must check the reference with "pat_ref_lookup()"
2015
 * or pat_ref_lookupid before calling this function. If the function
2016
 * fails, it returns NULL, otherwise it returns the new struct pat_ref.
2017
 */
2018
struct pat_ref *pat_ref_newid(int unique_id, const char *display, unsigned int flags)
2019
0
{
2020
0
  struct pat_ref *ref;
2021
2022
0
  ref = _pat_ref_new(display, flags);
2023
0
  if (!ref)
2024
0
    return NULL;
2025
2026
0
  ref->unique_id = unique_id;
2027
2028
0
  LIST_APPEND(&pattern_reference, &ref->list);
2029
0
  return ref;
2030
0
}
2031
2032
/* This function adds entry to <ref>. It can fail on memory error. It returns
2033
 * the newly added element on success, or NULL on failure. The PATREF_LOCK on
2034
 * <ref> must be held. It sets the newly created pattern's generation number
2035
 * to the same value as the reference's.
2036
 */
2037
struct pat_ref_elt *pat_ref_append(struct pat_ref *ref, unsigned int gen_id,
2038
                                   const char *pattern, const char *sample, int line)
2039
0
{
2040
0
  struct pat_ref_gen *gen;
2041
0
  struct pat_ref_elt *elt;
2042
0
  int len = strlen(pattern);
2043
2044
0
  elt = calloc(1, sizeof(*elt) + len + 1);
2045
0
  if (!elt)
2046
0
    goto fail;
2047
2048
0
  gen = pat_ref_gen_get(ref, gen_id);
2049
0
  if (!gen) {
2050
0
    gen = pat_ref_gen_new(ref, gen_id);
2051
0
    if (!gen)
2052
0
      goto fail;
2053
0
  }
2054
2055
0
  elt->gen_id = gen_id;
2056
0
  elt->line = line;
2057
2058
0
  memcpy((char*)elt->pattern, pattern, len + 1);
2059
2060
0
  if (sample) {
2061
0
    elt->sample = strdup(sample);
2062
0
    if (!elt->sample)
2063
0
      goto fail;
2064
0
  }
2065
2066
0
  LIST_INIT(&elt->back_refs);
2067
0
  elt->list_head = NULL;
2068
0
  elt->tree_head = NULL;
2069
0
  LIST_APPEND(&gen->head, &elt->list);
2070
0
  cebs_item_insert(&gen->elt_root, node, pattern, elt);
2071
0
  HA_ATOMIC_INC(&patterns_added);
2072
0
  return elt;
2073
0
 fail:
2074
0
  free(elt);
2075
0
  return NULL;
2076
0
}
2077
2078
/* This function creates sample found in <elt>, parses the pattern also
2079
 * found in <elt> and inserts it in <expr>. The function copies <patflags>
2080
 * into <expr>. If the function fails, it returns 0 and <err> is filled.
2081
 * In success case, the function returns 1.
2082
 */
2083
int pat_ref_push(struct pat_ref_elt *elt, struct pattern_expr *expr,
2084
                 int patflags, char **err)
2085
0
{
2086
0
  struct sample_data *data;
2087
0
  struct pattern pattern;
2088
2089
  /* Create sample */
2090
0
  if (elt->sample && expr->pat_head->parse_smp) {
2091
    /* New sample. */
2092
0
    data = malloc(sizeof(*data));
2093
0
    if (!data)
2094
0
      return 0;
2095
2096
    /* Parse value. */
2097
0
    if (!expr->pat_head->parse_smp(elt->sample, data)) {
2098
0
      memprintf(err, "unable to parse '%s'", elt->sample);
2099
0
      free(data);
2100
0
      return 0;
2101
0
    }
2102
2103
0
  }
2104
0
  else
2105
0
    data = NULL;
2106
2107
  /* initialise pattern */
2108
0
  memset(&pattern, 0, sizeof(pattern));
2109
0
  pattern.data = data;
2110
0
  pattern.ref = elt;
2111
2112
  /* parse pattern */
2113
0
  if (!expr->pat_head->parse(elt->pattern, &pattern, expr->mflags, err)) {
2114
0
    free(data);
2115
0
    return 0;
2116
0
  }
2117
2118
0
  HA_RWLOCK_WRLOCK(PATEXP_LOCK, &expr->lock);
2119
  /* index pattern */
2120
0
  if (!expr->pat_head->index(expr, &pattern, err)) {
2121
0
    HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
2122
0
    free(data);
2123
0
    return 0;
2124
0
  }
2125
0
  HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
2126
2127
0
  return 1;
2128
0
}
2129
2130
/* This function tries to commit entry <elt> into <ref>. The new entry must
2131
 * have already been inserted using pat_ref_append(), and its generation number
2132
 * may have been adjusted as it will not be changed. <err> must point to a NULL
2133
 * pointer. The PATREF lock on <ref> must be held. All the pattern_expr for
2134
 * this reference will be updated (parsing, indexing). On success, non-zero is
2135
 * returned. On failure, all the operation is rolled back (the element is
2136
 * deleted from all expressions and is freed), zero is returned and the error
2137
 * pointer <err> may have been updated (and the caller must free it). Failure
2138
 * causes include memory allocation, parsing error or indexing error.
2139
 */
2140
int pat_ref_commit_elt(struct pat_ref *ref, struct pat_ref_elt *elt, char **err)
2141
0
{
2142
0
  struct pattern_expr *expr;
2143
2144
0
  list_for_each_entry(expr, &ref->pat, list) {
2145
0
    if (!pat_ref_push(elt, expr, 0, err)) {
2146
0
      pat_ref_delete_by_ptr(ref, elt);
2147
0
      return 0;
2148
0
    }
2149
0
  }
2150
0
  return 1;
2151
0
}
2152
2153
/* Loads <pattern>:<sample> into <ref> for generation <gen>. <sample> may be
2154
 * NULL if none exists (e.g. ACL). If not needed, the generation number should
2155
 * be set to ref->curr_gen. The error pointer must initially point to NULL. The
2156
 * new entry will be propagated to all use places, involving allocation, parsing
2157
 * and indexing. On error (parsing, allocation), the operation will be rolled
2158
 * back, an error may be reported, and NULL will be reported. On success, the
2159
 * freshly allocated element will be returned. The PATREF lock on <ref> must be
2160
 * held during the operation.
2161
 */
2162
struct pat_ref_elt *pat_ref_load(struct pat_ref *ref, unsigned int gen,
2163
                                 const char *pattern, const char *sample,
2164
                                 int line, char **err)
2165
0
{
2166
0
  struct pat_ref_elt *elt;
2167
2168
0
  elt = pat_ref_append(ref, gen, pattern, sample, line);
2169
0
  if (elt) {
2170
0
    if (!pat_ref_commit_elt(ref, elt, err))
2171
0
      elt = NULL;
2172
0
  } else
2173
0
    memprintf(err, "out of memory error");
2174
2175
  /* ignore if update requires committing to be seen */
2176
0
  if (elt && gen == ref->curr_gen)
2177
0
    event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_ADD, NULL);
2178
2179
0
  return elt;
2180
0
}
2181
2182
/* This function adds entry to <ref>. It can fail on memory error. The new
2183
 * entry is added at all the pattern_expr registered in this reference. The
2184
 * function stops on the first error encountered. It returns 0 and <err> is
2185
 * filled. If an error is encountered, the complete add operation is cancelled.
2186
 * If the insertion is a success the function returns 1.
2187
 */
2188
int pat_ref_add(struct pat_ref *ref,
2189
                const char *pattern, const char *sample,
2190
                char **err)
2191
0
{
2192
0
  return !!pat_ref_load(ref, ref->curr_gen, pattern, sample, -1, err);
2193
0
}
2194
2195
/* This function purges all elements from <ref> whose generation is included in
2196
 * the range of <from> to <to> (inclusive), taking wrapping into consideration.
2197
 * It will not purge more than <budget> entries at once, in order to remain
2198
 * responsive. If budget is negative, no limit is applied.
2199
 * The caller must already hold the PATREF_LOCK on <ref>. The function will
2200
 * take the PATEXP_LOCK on all expressions of the pattern as needed. It returns
2201
 * non-zero on completion, or zero if it had to stop before the end after
2202
 * <budget> was depleted.
2203
 */
2204
int pat_ref_purge_range(struct pat_ref *ref, uint from, uint to, int budget)
2205
0
{
2206
0
  struct pat_ref_gen *gen, *gen2;
2207
0
  struct pat_ref_elt *elt, *elt_bck;
2208
0
  struct bref *bref, *bref_bck;
2209
0
  struct pattern_expr *expr;
2210
0
  int done;
2211
2212
0
  list_for_each_entry(expr, &ref->pat, list)
2213
0
    HA_RWLOCK_WRLOCK(PATEXP_LOCK, &expr->lock);
2214
2215
  /* all expr are locked, we can safely remove all pat_ref */
2216
2217
  /* assume completion for e.g. empty lists */
2218
0
  done = 1;
2219
0
  pat_ref_gen_foreach_safe(gen, gen2, ref) {
2220
0
    if (gen->gen_id - from > to - from) {
2221
0
      if (from <= to) {
2222
0
        break;
2223
0
      }
2224
0
      continue;
2225
0
    }
2226
2227
0
    list_for_each_entry_safe(elt, elt_bck, &gen->head, list) {
2228
0
      if (budget >= 0 && !budget--) {
2229
0
        done = 0;
2230
0
        break;
2231
0
      }
2232
2233
0
      BUG_ON(elt->gen_id != gen->gen_id);
2234
2235
      /*
2236
       * we have to unlink all watchers from this reference pattern. We must
2237
       * not relink them if this elt was the last one in the list.
2238
       */
2239
0
      list_for_each_entry_safe(bref, bref_bck, &elt->back_refs, users) {
2240
0
        LIST_DELETE(&bref->users);
2241
0
        LIST_INIT(&bref->users);
2242
0
        if (elt->list.n != &gen->head)
2243
0
          LIST_APPEND(&LIST_ELEM(elt->list.n, typeof(elt), list)->back_refs, &bref->users);
2244
0
        bref->ref = elt->list.n;
2245
0
      }
2246
2247
      /* delete the storage for all representations of this pattern. */
2248
0
      pat_delete_gen(ref, elt);
2249
2250
0
      LIST_DELETE(&elt->list);
2251
0
      cebs_item_delete(&gen->elt_root, node, pattern, elt);
2252
0
      free(elt->sample);
2253
0
      free(elt);
2254
0
      HA_ATOMIC_INC(&patterns_freed);
2255
0
    }
2256
2257
0
    if (!done)
2258
0
      break;
2259
2260
0
    BUG_ON(!LIST_ISEMPTY(&gen->head));
2261
0
    BUG_ON(!ceb_isempty(&gen->elt_root));
2262
0
    cebu32_item_delete(&ref->gen_root, gen_node, gen_id, gen);
2263
0
    if (gen->gen_id == ref->cached_gen.id)
2264
0
      ref->cached_gen.data = NULL;
2265
0
    free(gen);
2266
0
  }
2267
2268
0
  list_for_each_entry(expr, &ref->pat, list)
2269
0
    HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &expr->lock);
2270
2271
  /* only publish when we're done and if curr_gen was impacted by the
2272
   * purge
2273
   */
2274
0
  if (done && ref->curr_gen - from <= to - from)
2275
0
    event_hdl_publish(&ref->e_subs, EVENT_HDL_SUB_PAT_REF_CLEAR, NULL);
2276
2277
0
  return done;
2278
0
}
2279
2280
/* This function prunes all entries of <ref> and all their associated
2281
 * pattern_expr. It may return before the end of the list is reached,
2282
 * returning 0, to yield, indicating to the caller that it must call it again.
2283
 * until it returns non-zero. All patterns are purged, both current ones and
2284
 * future or incomplete ones. This is used by "clear map" or "clear acl".
2285
 */
2286
int pat_ref_prune(struct pat_ref *ref)
2287
0
{
2288
0
  return pat_ref_purge_range(ref, 0, ~0, 100);
2289
0
}
2290
2291
/* This function looks up any existing reference <ref> in pattern_head <head>, and
2292
 * returns the associated pattern_expr pointer if found, otherwise NULL.
2293
 */
2294
struct pattern_expr *pattern_lookup_expr(struct pattern_head *head, struct pat_ref *ref)
2295
0
{
2296
0
  struct pattern_expr_list *expr;
2297
2298
0
  list_for_each_entry(expr, &head->head, list)
2299
0
    if (expr->expr->ref == ref)
2300
0
      return expr->expr;
2301
0
  return NULL;
2302
0
}
2303
2304
/* This function creates new pattern_expr associated to the reference <ref>.
2305
 * <ref> can be NULL. If an error occurs, the function returns NULL and
2306
 * <err> is filled. Otherwise, the function returns new pattern_expr linked
2307
 * with <head> and <ref>.
2308
 *
2309
 * The returned value can be an already filled pattern list, in this case the
2310
 * flag <reuse> is set.
2311
 */
2312
struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref,
2313
                                      int patflags, char **err, int *reuse)
2314
0
{
2315
0
  struct pattern_expr *expr;
2316
0
  struct pattern_expr_list *list;
2317
2318
0
  if (reuse)
2319
0
    *reuse = 0;
2320
2321
  /* Memory and initialization of the chain element. */
2322
0
  list = calloc(1, sizeof(*list));
2323
0
  if (!list) {
2324
0
    memprintf(err, "out of memory");
2325
0
    return NULL;
2326
0
  }
2327
2328
  /* Look for existing similar expr. No that only the index, parse and
2329
   * parse_smp function must be identical for having similar pattern.
2330
   * The other function depends of these first.
2331
   */
2332
0
  if (ref) {
2333
0
    list_for_each_entry(expr, &ref->pat, list)
2334
0
      if (expr->pat_head->index     == head->index &&
2335
0
          expr->pat_head->parse     == head->parse &&
2336
0
          expr->pat_head->parse_smp == head->parse_smp &&
2337
0
          expr->mflags == patflags)
2338
0
        break;
2339
0
    if (&expr->list == &ref->pat)
2340
0
      expr = NULL;
2341
0
  }
2342
0
  else
2343
0
    expr = NULL;
2344
2345
  /* If no similar expr was found, we create new expr. */
2346
0
  if (!expr) {
2347
    /* Get a lot of memory for the expr struct. */
2348
0
    expr = calloc(1, sizeof(*expr));
2349
0
    if (!expr) {
2350
0
      free(list);
2351
0
      memprintf(err, "out of memory");
2352
0
      return NULL;
2353
0
    }
2354
2355
    /* Initialize this new expr. */
2356
0
    pattern_init_expr(expr);
2357
2358
    /* Copy the pattern matching and indexing flags. */
2359
0
    expr->mflags = patflags;
2360
2361
    /* This new pattern expression reference one of his heads. */
2362
0
    expr->pat_head = head;
2363
2364
    /* Link with ref, or to self to facilitate LIST_DELETE() */
2365
0
    if (ref)
2366
0
      LIST_APPEND(&ref->pat, &expr->list);
2367
0
    else
2368
0
      LIST_INIT(&expr->list);
2369
2370
0
    expr->ref = ref;
2371
2372
0
    HA_RWLOCK_INIT(&expr->lock);
2373
0
  }
2374
0
  else {
2375
0
    if (reuse)
2376
0
      *reuse = 1;
2377
0
  }
2378
2379
0
  HA_ATOMIC_INC(&expr->refcount);
2380
2381
  /* The new list element reference the pattern_expr. */
2382
0
  list->expr = expr;
2383
2384
  /* Link the list element with the pattern_head. */
2385
0
  LIST_APPEND(&head->head, &list->list);
2386
0
  return expr;
2387
0
}
2388
2389
/* Reads patterns from a file. If <err_msg> is non-NULL, an error message will
2390
 * be returned there on errors and the caller will have to free it.
2391
 *
2392
 * The file contains one key + value per line. Lines which start with '#' are
2393
 * ignored, just like empty lines. Leading tabs/spaces are stripped. The key is
2394
 * then the first "word" (series of non-space/tabs characters), and the value is
2395
 * what follows this series of space/tab till the end of the line excluding
2396
 * trailing spaces/tabs.
2397
 *
2398
 * Example :
2399
 *
2400
 *     # this is a comment and is ignored
2401
 *        62.212.114.60     1wt.eu      \n
2402
 *     <-><-----------><---><----><---->
2403
 *      |       |        |     |     `--- trailing spaces ignored
2404
 *      |       |        |      `-------- value
2405
 *      |       |        `--------------- middle spaces ignored
2406
 *      |       `------------------------ key
2407
 *      `-------------------------------- leading spaces ignored
2408
 *
2409
 * Return non-zero in case of success, otherwise 0.
2410
 */
2411
int pat_ref_read_from_file_smp(struct pat_ref *ref, char **err)
2412
0
{
2413
0
  FILE *file;
2414
0
  char *c;
2415
0
  int ret = 0;
2416
0
  int line = 0;
2417
0
  char *key_beg;
2418
0
  char *key_end;
2419
0
  char *value_beg;
2420
0
  char *value_end;
2421
2422
0
  file = fopen(ref->reference, "r");
2423
0
  if (!file) {
2424
0
    if (ref->flags & PAT_REF_ID) {
2425
      /* file not found for an optional file, switch it to a virtual list of patterns */
2426
0
      ref->flags &= ~PAT_REF_FILE;
2427
0
      return 1;
2428
0
    }
2429
0
    memprintf(err, "failed to open pattern file <%s>", ref->reference);
2430
0
    return 0;
2431
0
  }
2432
0
  ref->flags |= PAT_REF_FILE;
2433
2434
  /* now parse all patterns. The file may contain only one pattern
2435
   * followed by one value per line. The start spaces, separator spaces
2436
   * and and spaces are stripped. Each can contain comment started by '#'
2437
   */
2438
0
  while (fgets(trash.area, trash.size, file) != NULL) {
2439
0
    line++;
2440
0
    c = trash.area;
2441
2442
    /* ignore lines beginning with a dash */
2443
0
    if (*c == '#')
2444
0
      continue;
2445
2446
    /* strip leading spaces and tabs */
2447
0
    while (*c == ' ' || *c == '\t')
2448
0
      c++;
2449
2450
    /* empty lines are ignored too */
2451
0
    if (*c == '\0' || *c == '\r' || *c == '\n')
2452
0
      continue;
2453
2454
    /* look for the end of the key */
2455
0
    key_beg = c;
2456
0
    while (*c && *c != ' ' && *c != '\t' && *c != '\n' && *c != '\r')
2457
0
      c++;
2458
2459
0
    key_end = c;
2460
2461
    /* strip middle spaces and tabs */
2462
0
    while (*c == ' ' || *c == '\t')
2463
0
      c++;
2464
2465
    /* look for the end of the value, it is the end of the line */
2466
0
    value_beg = c;
2467
0
    while (*c && *c != '\n' && *c != '\r')
2468
0
      c++;
2469
0
    value_end = c;
2470
2471
    /* trim possibly trailing spaces and tabs */
2472
0
    while (value_end > value_beg && (value_end[-1] == ' ' || value_end[-1] == '\t'))
2473
0
      value_end--;
2474
2475
    /* set final \0 and check entries */
2476
0
    *key_end = '\0';
2477
0
    *value_end = '\0';
2478
2479
    /* insert values */
2480
0
    if (!pat_ref_append(ref, ref->curr_gen, key_beg, value_beg, line)) {
2481
0
      memprintf(err, "out of memory");
2482
0
      goto out_close;
2483
0
    }
2484
0
  }
2485
2486
0
  if (ferror(file)) {
2487
0
    memprintf(err, "error encountered while reading  <%s> : %s",
2488
0
        ref->reference, strerror(errno));
2489
0
    goto out_close;
2490
0
  }
2491
  /* success */
2492
0
  ret = 1;
2493
2494
0
 out_close:
2495
0
  fclose(file);
2496
0
  return ret;
2497
0
}
2498
2499
/* Reads patterns from a file. If <err_msg> is non-NULL, an error message will
2500
 * be returned there on errors and the caller will have to free it.
2501
 */
2502
int pat_ref_read_from_file(struct pat_ref *ref, char **err)
2503
0
{
2504
0
  FILE *file;
2505
0
  char *c;
2506
0
  char *arg;
2507
0
  int ret = 0;
2508
0
  int line = 0;
2509
2510
0
  file = fopen(ref->reference, "r");
2511
0
  if (!file) {
2512
0
    if (ref->flags & PAT_REF_ID) {
2513
      /* file not found for an optional file, switch it to a virtual list of patterns */
2514
0
      ref->flags &= ~PAT_REF_FILE;
2515
0
      return 1;
2516
0
    }
2517
0
    memprintf(err, "failed to open pattern file <%s>", ref->reference);
2518
0
    return 0;
2519
0
  }
2520
2521
  /* now parse all patterns. The file may contain only one pattern per
2522
   * line. If the line contains spaces, they will be part of the pattern.
2523
   * The pattern stops at the first CR, LF or EOF encountered.
2524
   */
2525
0
  while (fgets(trash.area, trash.size, file) != NULL) {
2526
0
    line++;
2527
0
    c = trash.area;
2528
2529
    /* ignore lines beginning with a dash */
2530
0
    if (*c == '#')
2531
0
      continue;
2532
2533
    /* strip leading spaces and tabs */
2534
0
    while (*c == ' ' || *c == '\t')
2535
0
      c++;
2536
2537
2538
0
    arg = c;
2539
0
    while (*c && *c != '\n' && *c != '\r')
2540
0
      c++;
2541
0
    *c = 0;
2542
2543
    /* empty lines are ignored too */
2544
0
    if (c == arg)
2545
0
      continue;
2546
2547
0
    if (!pat_ref_append(ref, ref->curr_gen, arg, NULL, line)) {
2548
0
      memprintf(err, "out of memory when loading patterns from file <%s>", ref->reference);
2549
0
      goto out_close;
2550
0
    }
2551
0
  }
2552
2553
0
  if (ferror(file)) {
2554
0
    memprintf(err, "error encountered while reading  <%s> : %s",
2555
0
        ref->reference, strerror(errno));
2556
0
    goto out_close;
2557
0
  }
2558
0
  ret = 1; /* success */
2559
2560
0
 out_close:
2561
0
  fclose(file);
2562
0
  return ret;
2563
0
}
2564
2565
int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
2566
                           const char *filename, int patflags, int load_smp,
2567
                           char **err, const char *file, int line)
2568
0
{
2569
0
  struct pat_ref *ref;
2570
0
  struct pattern_expr *expr;
2571
0
  struct pat_ref_gen *gen;
2572
0
  struct pat_ref_elt *elt;
2573
0
  int reuse = 0;
2574
2575
  /* Lookup for the existing reference. */
2576
0
  ref = pat_ref_lookup(filename);
2577
2578
  /* If the reference doesn't exists, create it and load associated file. */
2579
0
  if (!ref) {
2580
0
    chunk_printf(&trash,
2581
0
                 "pattern loaded from file '%s' used by %s at file '%s' line %d",
2582
0
                 filename, refflags & PAT_REF_MAP ? "map" : "acl", file, line);
2583
2584
0
    ref = pat_ref_new(filename, trash.area, refflags);
2585
0
    if (!ref) {
2586
0
      memprintf(err, "out of memory");
2587
0
      return 0;
2588
0
    }
2589
2590
0
    if (ref->flags & PAT_REF_FILE) {
2591
0
      if (load_smp) {
2592
0
        ref->flags |= PAT_REF_SMP;
2593
0
        if (!pat_ref_read_from_file_smp(ref, err)) {
2594
0
          LIST_DELETE(&ref->list);
2595
0
          pat_ref_free(ref);
2596
0
          return 0;
2597
0
        }
2598
0
      }
2599
0
      else {
2600
0
        if (!pat_ref_read_from_file(ref, err)) {
2601
0
          LIST_DELETE(&ref->list);
2602
0
          pat_ref_free(ref);
2603
0
          return 0;
2604
0
        }
2605
0
      }
2606
0
    }
2607
0
    else if ((ref->flags & PAT_REF_ID) && load_smp)
2608
0
      ref->flags |= PAT_REF_SMP;
2609
0
  }
2610
0
  else {
2611
    /* The reference already exists, check the map compatibility. */
2612
2613
    /* If the load require samples and the flag PAT_REF_SMP is not set,
2614
     * the reference doesn't contain sample, and cannot be used.
2615
     */
2616
0
    if (load_smp) {
2617
0
      if (!(ref->flags & PAT_REF_SMP)) {
2618
0
        memprintf(err, "The file \"%s\" is already used as one column file "
2619
0
                       "and cannot be used by as two column file.",
2620
0
                       filename);
2621
0
        return 0;
2622
0
      }
2623
0
    }
2624
0
    else {
2625
      /* The load doesn't require samples. If the flag PAT_REF_SMP is
2626
       * set, the reference contains a sample, and cannot be used.
2627
       */
2628
0
      if (ref->flags & PAT_REF_SMP) {
2629
0
        memprintf(err, "The file \"%s\" is already used as two column file "
2630
0
                       "and cannot be used by as one column file.",
2631
0
                       filename);
2632
0
        return 0;
2633
0
      }
2634
0
    }
2635
2636
    /* Extends display */
2637
0
    chunk_printf(&trash, "%s", ref->display);
2638
0
    chunk_appendf(&trash, ", by %s at file '%s' line %d",
2639
0
                  refflags & PAT_REF_MAP ? "map" : "acl", file, line);
2640
0
    free(ref->display);
2641
0
    ref->display = strdup(trash.area);
2642
0
    if (!ref->display) {
2643
0
      memprintf(err, "out of memory");
2644
0
      return 0;
2645
0
    }
2646
2647
    /* Merge flags. */
2648
0
    ref->flags |= refflags;
2649
0
  }
2650
2651
  /* Now, we can loading patterns from the reference. */
2652
2653
  /* Lookup for existing reference in the head. If the reference
2654
   * doesn't exists, create it.
2655
   */
2656
0
  expr = pattern_lookup_expr(head, ref);
2657
0
  if (!expr || (expr->mflags != patflags)) {
2658
0
    expr = pattern_new_expr(head, ref, patflags, err, &reuse);
2659
0
    if (!expr)
2660
0
      return 0;
2661
0
  }
2662
2663
  /* The returned expression may be not empty, because the function
2664
   * "pattern_new_expr" lookup for similar pattern list and can
2665
   * reuse a already filled pattern list. In this case, we can not
2666
   * reload the patterns.
2667
   */
2668
0
  if (reuse)
2669
0
    return 1;
2670
2671
  /* Load reference content in the pattern expression.
2672
   * We need to load elements in the same order they were seen in the
2673
   * file. Indeed, some list-based matching types may rely on it as the
2674
   * list is positional, and for tree-based matching, even if the tree is
2675
   * content-based in case of duplicated keys we only want the first key
2676
   * in the file to be considered.
2677
   */
2678
0
  pat_ref_gen_foreach(gen, ref) {
2679
0
    list_for_each_entry(elt, &gen->head, list) {
2680
0
      if (!pat_ref_push(elt, expr, patflags, err)) {
2681
0
        if (elt->line > 0)
2682
0
          memprintf(err, "%s at line %d of file '%s'",
2683
0
            *err, elt->line, filename);
2684
0
        return 0;
2685
0
      }
2686
0
    }
2687
0
  }
2688
2689
0
  return 1;
2690
0
}
2691
2692
/* This function executes a pattern match on a sample. It applies pattern <expr>
2693
 * to sample <smp>. The function returns NULL if the sample don't match. It returns
2694
 * non-null if the sample match. If <fill> is true and the sample match, the
2695
 * function returns the matched pattern. In many cases, this pattern can be a
2696
 * static buffer.
2697
 */
2698
struct pattern *pattern_exec_match(struct pattern_head *head, struct sample *smp, int fill)
2699
0
{
2700
0
  struct pattern_expr_list *list;
2701
0
  struct pattern *pat;
2702
2703
0
  if (!head->match) {
2704
0
    if (fill) {
2705
0
      static_pattern.data = NULL;
2706
0
      static_pattern.ref = NULL;
2707
0
      static_pattern.sflags = 0;
2708
0
      static_pattern.type = SMP_T_SINT;
2709
0
      static_pattern.val.i = 1;
2710
0
    }
2711
0
    return &static_pattern;
2712
0
  }
2713
2714
  /* convert input to string */
2715
0
  if (!sample_convert(smp, head->expect_type))
2716
0
    return NULL;
2717
2718
0
  list_for_each_entry(list, &head->head, list) {
2719
0
    HA_RWLOCK_RDLOCK(PATEXP_LOCK, &list->expr->lock);
2720
0
    pat = head->match(smp, list->expr, fill);
2721
0
    if (pat) {
2722
      /* We duplicate the pattern cause it could be modified
2723
         by another thread */
2724
0
      if (pat != &static_pattern) {
2725
0
        memcpy(&static_pattern, pat, sizeof(struct pattern));
2726
0
        pat = &static_pattern;
2727
0
      }
2728
2729
      /* We also duplicate the sample data for
2730
         same reason */
2731
0
      if (pat->data && (pat->data != &static_sample_data)) {
2732
0
        switch(pat->data->type) {
2733
0
          case SMP_T_STR:
2734
0
            static_sample_data.type = SMP_T_STR;
2735
0
            static_sample_data.u.str = *get_trash_chunk();
2736
0
            static_sample_data.u.str.data = pat->data->u.str.data;
2737
0
            if (static_sample_data.u.str.data >= static_sample_data.u.str.size)
2738
0
              static_sample_data.u.str.data = static_sample_data.u.str.size - 1;
2739
0
            memcpy(static_sample_data.u.str.area,
2740
0
                   pat->data->u.str.area, static_sample_data.u.str.data);
2741
0
            static_sample_data.u.str.area[static_sample_data.u.str.data] = 0;
2742
0
            pat->data = &static_sample_data;
2743
0
            break;
2744
2745
0
          case SMP_T_IPV4:
2746
0
          case SMP_T_IPV6:
2747
0
          case SMP_T_SINT:
2748
0
            memcpy(&static_sample_data, pat->data, sizeof(struct sample_data));
2749
0
            pat->data = &static_sample_data;
2750
0
            break;
2751
0
          default:
2752
            /* unimplemented pattern type */
2753
0
            pat->data = NULL;
2754
0
            break;
2755
0
        }
2756
0
      }
2757
0
      HA_RWLOCK_RDUNLOCK(PATEXP_LOCK, &list->expr->lock);
2758
0
      return pat;
2759
0
    }
2760
0
    HA_RWLOCK_RDUNLOCK(PATEXP_LOCK, &list->expr->lock);
2761
0
  }
2762
0
  return NULL;
2763
0
}
2764
2765
/* This function prunes the pattern expressions starting at pattern_head <head>. */
2766
void pattern_prune(struct pattern_head *head)
2767
0
{
2768
0
  struct pattern_expr_list *list, *safe;
2769
2770
0
  list_for_each_entry_safe(list, safe, &head->head, list) {
2771
0
    LIST_DELETE(&list->list);
2772
0
    if (HA_ATOMIC_SUB_FETCH(&list->expr->refcount, 1) == 0) {
2773
0
      LIST_DELETE(&list->expr->list);
2774
0
      HA_RWLOCK_WRLOCK(PATEXP_LOCK, &list->expr->lock);
2775
0
      head->prune(list->expr);
2776
0
      HA_RWLOCK_WRUNLOCK(PATEXP_LOCK, &list->expr->lock);
2777
0
      free(list->expr);
2778
0
    }
2779
0
    free(list);
2780
0
  }
2781
0
}
2782
2783
/* This function compares two pat_ref** on their unique_id, and returns -1/0/1
2784
 * depending on their order (suitable for sorting).
2785
 */
2786
static int cmp_pat_ref(const void *_a, const void *_b)
2787
0
{
2788
0
  struct pat_ref * const *a = _a;
2789
0
  struct pat_ref * const *b = _b;
2790
2791
0
  if ((*a)->unique_id < (*b)->unique_id)
2792
0
    return -1;
2793
0
  else if ((*a)->unique_id > (*b)->unique_id)
2794
0
    return 1;
2795
0
  return 0;
2796
0
}
2797
2798
/* This function finalizes the configuration parsing. It sets all the
2799
 * automatic ids.
2800
 */
2801
int pattern_finalize_config(void)
2802
0
{
2803
0
  size_t len = 0;
2804
0
  size_t unassigned_pos = 0;
2805
0
  int next_unique_id = 0;
2806
0
  size_t i, j;
2807
0
  struct pat_ref *ref, **arr;
2808
0
  struct list pr = LIST_HEAD_INIT(pr);
2809
2810
0
  pat_lru_seed = ha_random();
2811
2812
  /* Count pat_refs with user defined unique_id and totalt count */
2813
0
  list_for_each_entry(ref, &pattern_reference, list) {
2814
0
    len++;
2815
0
    if (ref->unique_id != -1)
2816
0
      unassigned_pos++;
2817
0
  }
2818
2819
0
  if (len == 0) {
2820
0
    return 0;
2821
0
  }
2822
2823
0
  arr = calloc(len, sizeof(*arr));
2824
0
  if (arr == NULL) {
2825
0
    ha_alert("Out of memory error.\n");
2826
0
    return ERR_ALERT | ERR_FATAL;
2827
0
  }
2828
2829
0
  i = 0;
2830
0
  j = unassigned_pos;
2831
0
  list_for_each_entry(ref, &pattern_reference, list) {
2832
0
    if (ref->unique_id != -1)
2833
0
      arr[i++] = ref;
2834
0
    else
2835
0
      arr[j++] = ref;
2836
0
  }
2837
2838
  /* Sort first segment of array with user-defined unique ids for
2839
   * fast lookup when generating unique ids
2840
   */
2841
0
  qsort(arr, unassigned_pos, sizeof(*arr), cmp_pat_ref);
2842
2843
  /* Assign unique ids to the rest of the elements */
2844
0
  for (i = unassigned_pos; i < len; i++) {
2845
0
    do {
2846
0
      arr[i]->unique_id = next_unique_id++;
2847
0
    } while (bsearch(&arr[i], arr, unassigned_pos, sizeof(*arr), cmp_pat_ref));
2848
0
  }
2849
2850
  /* Sort complete array */
2851
0
  qsort(arr, len, sizeof(*arr), cmp_pat_ref);
2852
2853
  /* Convert back to linked list */
2854
0
  for (i = 0; i < len; i++)
2855
0
    LIST_APPEND(&pr, &arr[i]->list);
2856
2857
  /* swap root */
2858
0
  LIST_INSERT(&pr, &pattern_reference);
2859
0
  LIST_DELETE(&pr);
2860
2861
0
  free(arr);
2862
0
  return 0;
2863
0
}
2864
2865
static int pattern_per_thread_lru_alloc()
2866
0
{
2867
0
  if (!global.tune.pattern_cache)
2868
0
    return 1;
2869
0
  pat_lru_tree = lru64_new(global.tune.pattern_cache);
2870
0
  return !!pat_lru_tree;
2871
0
}
2872
2873
static void pattern_per_thread_lru_free()
2874
0
{
2875
0
  lru64_destroy(pat_lru_tree);
2876
0
}
2877
2878
REGISTER_PER_THREAD_ALLOC(pattern_per_thread_lru_alloc);
2879
REGISTER_PER_THREAD_FREE(pattern_per_thread_lru_free);