mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-17 17:04:35 +00:00
MEDIUM: pattern: only match patterns that match the current generation
Instead of matching any pattern found in the tree, only match those matching the current generation of entries. This will make sure that reloads are atomic, regardless of the time they take to complete, and that newly added data are not matched until the whole reference is committed. For consistency we proceed the same way on "show map" and "show acl". This will have no impact for now since generations are not used.
This commit is contained in:
parent
29947745b5
commit
c93da6950e
@ -368,6 +368,9 @@ static int cli_io_handler_pat_list(struct appctx *appctx)
|
||||
|
||||
elt = LIST_ELEM(appctx->ctx.map.bref.ref, struct pat_ref_elt *, list);
|
||||
|
||||
if (elt->gen_id != appctx->ctx.map.ref->curr_gen)
|
||||
goto skip;
|
||||
|
||||
/* build messages */
|
||||
if (elt->sample)
|
||||
chunk_appendf(&trash, "%p %s %s\n",
|
||||
@ -386,7 +389,7 @@ static int cli_io_handler_pat_list(struct appctx *appctx)
|
||||
si_rx_room_blk(si);
|
||||
return 0;
|
||||
}
|
||||
|
||||
skip:
|
||||
/* get next list entry and check the end of the list */
|
||||
appctx->ctx.map.bref.ref = elt->list.n;
|
||||
}
|
||||
|
@ -465,9 +465,14 @@ struct pattern *pat_match_str(struct sample *smp, struct pattern_expr *expr, int
|
||||
node = ebst_lookup(&expr->pattern_tree, smp->data.u.str.area);
|
||||
if (prev)
|
||||
smp->data.u.str.area[smp->data.u.str.data] = prev;
|
||||
if (node) {
|
||||
|
||||
while (node) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
if (elt->ref->gen_id != expr->ref->curr_gen) {
|
||||
node = ebmb_next(node);
|
||||
continue;
|
||||
}
|
||||
if (fill) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.data = elt->data;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
@ -494,6 +499,9 @@ struct pattern *pat_match_str(struct sample *smp, struct pattern_expr *expr, int
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if (pattern->len != smp->data.u.str.data)
|
||||
continue;
|
||||
|
||||
@ -533,6 +541,9 @@ struct pattern *pat_match_bin(struct sample *smp, struct pattern_expr *expr, int
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if (pattern->len != smp->data.u.str.data)
|
||||
continue;
|
||||
|
||||
@ -561,6 +572,9 @@ struct pattern *pat_match_regm(struct sample *smp, struct pattern_expr *expr, in
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if (regex_exec_match2(pattern->ptr.reg, smp->data.u.str.area, smp->data.u.str.data,
|
||||
MAX_MATCH, pmatch, 0)) {
|
||||
ret = pattern;
|
||||
@ -596,6 +610,9 @@ struct pattern *pat_match_reg(struct sample *smp, struct pattern_expr *expr, int
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if (regex_exec2(pattern->ptr.reg, smp->data.u.str.area, smp->data.u.str.data)) {
|
||||
ret = pattern;
|
||||
break;
|
||||
@ -644,9 +661,13 @@ struct pattern *pat_match_beg(struct sample *smp, struct pattern_expr *expr, int
|
||||
if (prev)
|
||||
smp->data.u.str.area[smp->data.u.str.data] = prev;
|
||||
|
||||
if (node) {
|
||||
while (node) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
if (elt->ref->gen_id != expr->ref->curr_gen) {
|
||||
node = ebmb_next(node);
|
||||
continue;
|
||||
}
|
||||
if (fill) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.data = elt->data;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
@ -672,6 +693,9 @@ struct pattern *pat_match_beg(struct sample *smp, struct pattern_expr *expr, int
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if (pattern->len > smp->data.u.str.data)
|
||||
continue;
|
||||
|
||||
@ -713,6 +737,9 @@ struct pattern *pat_match_end(struct sample *smp, struct pattern_expr *expr, int
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if (pattern->len > smp->data.u.str.data)
|
||||
continue;
|
||||
|
||||
@ -758,6 +785,9 @@ struct pattern *pat_match_sub(struct sample *smp, struct pattern_expr *expr, int
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if (pattern->len > smp->data.u.str.data)
|
||||
continue;
|
||||
|
||||
@ -856,6 +886,10 @@ struct pattern *pat_match_dir(struct sample *smp, struct pattern_expr *expr, int
|
||||
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if (match_word(smp, pattern, expr->mflags, make_4delim('/', '?', '?', '?')))
|
||||
return pattern;
|
||||
}
|
||||
@ -873,6 +907,10 @@ struct pattern *pat_match_dom(struct sample *smp, struct pattern_expr *expr, int
|
||||
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if (match_word(smp, pattern, expr->mflags, make_4delim('/', '?', '.', ':')))
|
||||
return pattern;
|
||||
}
|
||||
@ -887,6 +925,10 @@ struct pattern *pat_match_int(struct sample *smp, struct pattern_expr *expr, int
|
||||
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.u.sint) &&
|
||||
(!pattern->val.range.max_set || smp->data.u.sint <= pattern->val.range.max))
|
||||
return pattern;
|
||||
@ -902,6 +944,10 @@ struct pattern *pat_match_len(struct sample *smp, struct pattern_expr *expr, int
|
||||
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.u.str.data) &&
|
||||
(!pattern->val.range.max_set || smp->data.u.str.data <= pattern->val.range.max))
|
||||
return pattern;
|
||||
@ -926,9 +972,13 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
|
||||
*/
|
||||
s = &smp->data.u.ipv4;
|
||||
node = ebmb_lookup_longest(&expr->pattern_tree, &s->s_addr);
|
||||
if (node) {
|
||||
while (node) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
if (elt->ref->gen_id != expr->ref->curr_gen) {
|
||||
node = ebmb_next(node);
|
||||
continue;
|
||||
}
|
||||
if (fill) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.data = elt->data;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
@ -948,9 +998,13 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
|
||||
write_u16(&tmp6.s6_addr[10], htons(0xffff));
|
||||
write_u32(&tmp6.s6_addr[12], smp->data.u.ipv4.s_addr);
|
||||
node = ebmb_lookup_longest(&expr->pattern_tree_2, &tmp6);
|
||||
if (node) {
|
||||
while (node) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
if (elt->ref->gen_id != expr->ref->curr_gen) {
|
||||
node = ebmb_next(node);
|
||||
continue;
|
||||
}
|
||||
if (fill) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.data = elt->data;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
@ -968,9 +1022,13 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
|
||||
* the longest match method.
|
||||
*/
|
||||
node = ebmb_lookup_longest(&expr->pattern_tree_2, &smp->data.u.ipv6);
|
||||
if (node) {
|
||||
while (node) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
if (elt->ref->gen_id != expr->ref->curr_gen) {
|
||||
node = ebmb_next(node);
|
||||
continue;
|
||||
}
|
||||
if (fill) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.data = elt->data;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
@ -1001,9 +1059,13 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
|
||||
* match method.
|
||||
*/
|
||||
node = ebmb_lookup_longest(&expr->pattern_tree, &v4);
|
||||
if (node) {
|
||||
while (node) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
if (elt->ref->gen_id != expr->ref->curr_gen) {
|
||||
node = ebmb_next(node);
|
||||
continue;
|
||||
}
|
||||
if (fill) {
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.data = elt->data;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
@ -1021,6 +1083,9 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
|
||||
if (pattern->ref->gen_id != expr->ref->curr_gen)
|
||||
continue;
|
||||
|
||||
/* The input sample is IPv4, use it as is. */
|
||||
if (smp->data.type == SMP_T_IPV4) {
|
||||
v4 = smp->data.u.ipv4.s_addr;
|
||||
|
Loading…
Reference in New Issue
Block a user