}
}
else if (strcmp(args[1], "expect") == 0) {
+ struct tcpcheck_rule *tcpcheck, *prev_check;
const char *ptr_arg;
int cur_arg;
int inverse = 0;
* exclamation mark, and cur_arg is the argument which holds this word.
*/
if (strcmp(ptr_arg, "binary") == 0) {
- struct tcpcheck_rule *tcpcheck;
char *err = NULL;
if (!*(args[cur_arg + 1])) {
}
tcpcheck->comment = strdup(args[cur_arg + 1]);
}
-
- LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
}
else if (strcmp(ptr_arg, "string") == 0) {
- struct tcpcheck_rule *tcpcheck;
-
if (!*(args[cur_arg + 1])) {
ha_alert("parsing [%s:%d] : '%s %s %s' expects <string> as an argument.\n",
file, linenum, args[0], args[1], ptr_arg);
}
tcpcheck->comment = strdup(args[cur_arg + 1]);
}
-
- LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
}
else if (strcmp(ptr_arg, "rstring") == 0) {
- struct tcpcheck_rule *tcpcheck;
-
if (!*(args[cur_arg + 1])) {
ha_alert("parsing [%s:%d] : '%s %s %s' expects <regex> as an argument.\n",
file, linenum, args[0], args[1], ptr_arg);
}
tcpcheck->comment = strdup(args[cur_arg + 1]);
}
-
- LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
}
else {
ha_alert("parsing [%s:%d] : '%s %s' only supports [!] 'binary', 'string', 'rstring', found '%s'.\n",
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
+
+ /* All tcp-check expect points back to the first inverse expect rule
+ * in a chain of one or more expect rule, potentially itself.
+ */
+ tcpcheck->expect_head = tcpcheck;
+ list_for_each_entry_rev(prev_check, &curproxy->tcpcheck_rules, list) {
+ if (prev_check->action == TCPCHK_ACT_EXPECT) {
+ if (prev_check->inverse)
+ tcpcheck->expect_head = prev_check;
+ continue;
+ }
+ if (prev_check->action != TCPCHK_ACT_COMMENT)
+ break;
+ }
+ LIST_ADDQ(&curproxy->tcpcheck_rules, &tcpcheck->list);
}
else {
ha_alert("parsing [%s:%d] : '%s' only supports 'comment', 'connect', 'send' or 'expect'.\n", file, linenum, args[0]);
}
}
+ /* Having received new data, reset the expect chain to its head. */
+ check->current_step = check->current_step->expect_head;
+
/* mark the step as started */
check->last_started_step = check->current_step;
tcpcheck_expect:
if (!done && (check->current_step->string != NULL) && (b_data(&check->bi) < check->current_step->string_len) )
continue; /* try to read more */
-
if (check->current_step->string != NULL)
ret = my_memmem(contentptr, b_data(&check->bi), check->current_step->string, check->current_step->string_len) != NULL;
else if (check->current_step->expect_regex != NULL)
static int add_tcpcheck_expect_str(struct list *list, const char *str)
{
- struct tcpcheck_rule *tcpcheck;
+ struct tcpcheck_rule *tcpcheck, *prev_check;
if ((tcpcheck = pool_alloc(pool_head_tcpcheck_rule)) == NULL)
return 0;
return 0;
}
+ /* All tcp-check expect points back to the first inverse expect rule
+ * in a chain of one or more expect rule, potentially itself.
+ */
+ tcpcheck->expect_head = tcpcheck;
+ list_for_each_entry_rev(prev_check, list, list) {
+ if (prev_check->action == TCPCHK_ACT_EXPECT) {
+ if (prev_check->inverse)
+ tcpcheck->expect_head = prev_check;
+ continue;
+ }
+ if (prev_check->action != TCPCHK_ACT_COMMENT)
+ break;
+ }
LIST_ADDQ(list, &tcpcheck->list);
return 1;
}