Skip to content

Commit

Permalink
Merge pull request #1036 from tempesta-tech/ao-1033
Browse files Browse the repository at this point in the history
Fix #1033: Change header name format in HTTP tables configuration.
  • Loading branch information
aleksostapenko authored Jul 18, 2018
2 parents ca3d197 + 736111f commit fd61c53
Show file tree
Hide file tree
Showing 8 changed files with 456 additions and 249 deletions.
32 changes: 9 additions & 23 deletions etc/tempesta_fw.conf
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@
#
# Syntax:
# http_chain {
# [ FIELD == (!=) ARG ] -> ACTION [ = VAL];
# [ FIELD [HDR_NAME] == (!=) ARG ] -> ACTION [ = VAL];
# ...
# }
#
Expand All @@ -259,28 +259,14 @@
# HTTP request method. Supported ARG values for this field are: "copy",
# "delete", "get", "head", "lock", "mkcol", "move", "options", "patch",
# "post", "propfind", "proppatch", "put", "trace", "unlock", "purge".
# - hdr_host
# The value of the "Host" header field.
# - hdr_conn
# The value of the "Connection" header field.
# - hdr_ctype
# The value of the "Content-Type" header field.
# - hdr_uagent
# The value of the "User-Agent" header field.
# - hdr_cookie
# The value of the "Cookie" header field.
# - hdr_ref
# The value of the "Referer" header field.
# - hdr_nmatch
# The value of the "If-None-Match" header field.
# - hdr_xfrwd
# The value of the "X-Forwarded-For" header field.
# - hdr_raw
# The contents of any other HTTP header field as specified by ARG.
# ARG must include contents of an HTTP header starting with the header
# field name. The suffix OP is not supported for this FIELD. Processing
# of hdr_raw may be slow as it requires walking over all headers of an
# HTTP request.
# - hdr
# The content of specific HTTP header. In this case HDR_NAME field is
# used to specify the name of header; the value of header should be
# specified in ARG. Matching of special headers: "X-Forwarded-For",
# "If-None-Match", "Referer", "Cookie", "User-Agent", "Content-Type",
# "Connection", "Host" - is accelerated; proccessing of other headers
# may be slow as it requires walking over all headers of an HTTP
# request. Also, suffix OP is not supported for not special headers.
# - mark
# The value of netfilter mark of request's skb.
#
Expand Down
45 changes: 40 additions & 5 deletions tempesta_fw/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ static inline void
rule_reset(TfwCfgRule *rule)
{
kfree(rule->fst);
kfree(rule->fst_ext);
kfree(rule->snd);
kfree(rule->act);
kfree(rule->val);
Expand Down Expand Up @@ -770,20 +771,23 @@ parse_cfg_entry(TfwCfgParserState *ps)

/* Every _PFSM_MOVE() invokes _read_next_token(), so when we enter
* any state, we get a new token automatically.
* Three different situations may occur here:
* Four different situations may occur here:
* 1. In case of plain directive parsing:
* name key = value;
* ^
* 2. In case of rule parsing:
* key == (!=) value -> action [= val]
* ^
* 3. In case of parsing of pure action rule:
* 3. In case of extended rule parsing:
* key key_ext == (!=) value -> action [= val]
* ^
* 4. In case of parsing of pure action rule:
* -> action [= val]
* ^
* current token is here; so at first we need to differentiate third
* situation, and in first two ones - save first token in special location
* current token is here; so at first we need to differentiate fourth
* situation, and in first three ones - save first token in special location
* to decide later whether use it as name for plain directive or as
* condition key for rule; in last two cases predefined rule name is used.
* condition key for rule; in last three cases predefined rule name is used.
*/
FSM_STATE(PS_START_NEW_ENTRY) {
entry_reset(&ps->e);
Expand All @@ -802,11 +806,42 @@ parse_cfg_entry(TfwCfgParserState *ps)
PFSM_COND_MOVE(ps->t == TOKEN_DEQSIGN ||
ps->t == TOKEN_NEQSIGN,
PS_RULE_COND);
PFSM_COND_MOVE(ps->t == TOKEN_LITERAL, PS_PLAIN_OR_LONG_RULE);

/* Jump to plain val/attr scheme to make remained checks
* for left brace and semicolon. */
ps->err = entry_set_name(&ps->e);
FSM_COND_JMP(ps->err, PS_EXIT);
FSM_JMP(PS_VAL_OR_ATTR);
}

FSM_STATE(PS_PLAIN_OR_LONG_RULE) {
FSM_COND_JMP(ps->t == TOKEN_DEQSIGN ||
ps->t == TOKEN_NEQSIGN,
PS_LONG_RULE_COND);

/* This is not rule (simple or extended), so jump to
* plain val/attr scheme. */
ps->err = entry_set_name(&ps->e);
FSM_COND_JMP(ps->err, PS_EXIT);
FSM_COND_JMP(ps->t == TOKEN_EQSIGN, PS_STORE_ATTR_PREV);
FSM_COND_JMP(ps->t == TOKEN_LITERAL ||
ps->t == TOKEN_SEMICOLON ||
ps->t == TOKEN_LBRACE,
PS_STORE_VAL_PREV);

ps->err = -EINVAL;
FSM_JMP(PS_EXIT);
}

FSM_STATE(PS_LONG_RULE_COND) {
ps->err = entry_add_rule_param(&ps->e.rule.fst_ext,
ps->prev_lit,
ps->prev_lit_len);
FSM_COND_JMP(ps->err, PS_EXIT);
PFSM_MOVE(PS_RULE_COND);
}

FSM_STATE(PS_RULE_COND) {
PFSM_COND_JMP_EXIT_ERROR(ps->t != TOKEN_LITERAL);
ps->err = entry_set_cond(&ps->e, ps->prev_t, ps->lit,
Expand Down
20 changes: 20 additions & 0 deletions tempesta_fw/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,25 @@
* comparison sign interpretation in rule condition part:
* "==" => false / "!=" => true
*
* Also extended rule form is used in case of specifying HTTP headers. Following
* rule:
* hdr "Referer" == "*example.com" -> mark = 7;
*
* will have following representaion:
* TfwCfgEntry {
* .name = "rule",
* ...
* .rule = {
* .fst = "hdr",
* .fst_ext = "Referer",
* .snd = "*example.com",
* .act = "mark",
* .val = "7",
* .inv = false
* },
* ...
* }
*
* @ftoken is an auxiliary internal field of TfwCfgEntry{} structure which
* helps parser to differentiate plain directives from rules.
*
Expand All @@ -125,6 +144,7 @@
*/
typedef struct {
const char *fst;
const char *fst_ext;
const char *snd;
const char *act;
const char *val;
Expand Down
Loading

0 comments on commit fd61c53

Please sign in to comment.