分类: 网络与安全
2013-07-20 11:38:36
原文地址:HAProxy 研究笔记 -- rules 实现 作者:Godbach
如果要实现功能丰富的 rules,需要有配套的 ACL 机制。
ACL 的格式如下:
acl[flags] [operator] ...
haproxy 中 ACL 数据结构的定义:
/* The acl will be linked to from the proxy where it is declared */
struct acl {
struct list list; /* chaining */
char *name; /* acl name */
struct list expr; /* list of acl_exprs */
int cache_idx; /* ACL index in cache */
unsigned int requires; /* or'ed bit mask of all acl_expr's ACL_USE_* */
};
其中:
函数 parse_acl() 负责解析定义好的 ACL:
总结: 一个 ACL 包含一到多个表达式。每个表达式包含一个 kw及一到多个 pattern。
这里简要描述 rule 与 acl 之间的逻辑关系:
struct acl_cond {
struct list list; /* Some specific tests may use multiple conditions */
struct list suites; /* list of acl_term_suites */
int pol; /* polarity: ACL_COND_IF / ACL_COND_UNLESS */
unsigned int requires; /* or'ed bit mask of all acl's ACL_USE_* */
const char *file; /* config file where the condition is declared */
int line; /* line in the config file where the condition is declared */
};
struct acl_term_suite {
struct list list; /* chaining of term suites */
struct list terms; /* list of acl_terms */
};
struct acl_term {
struct list list; /* chaining */
struct acl *acl; /* acl pointed to by this term */
int neg; /* 1 if the ACL result must be negated */
};
概括起来很简单,执行判断条件。符合条件,然后执行对应动作。
下面是 rspadd 的示例代码:
/* add response headers from the rule sets in the same order */
list_for_each_entry(wl, &rule_set->rsp_add, list) {
if (txn->status < 200)
break;
if (wl->cond) {
int ret = acl_exec_cond(wl->cond, px, t, txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
ret = acl_pass(ret);
if (((struct acl_cond *)wl->cond)->pol == ACL_COND_UNLESS)
ret = !ret;
if (!ret)
continue;
}
if (unlikely(http_header_add_tail(&txn->rsp, &txn->hdr_idx, wl->s) < 0))
goto return_bad_resp;
}
对于同一个种类的 rules,执行逻辑如下:
从 proxy 结构体可以看出 rule 的种类
struct proxy {
...
struct list acl; /* ACL declared on this proxy */
struct list http_req_rules; /* HTTP request rules: allow/deny/http-auth */
struct list block_cond; /* early blocking conditions (chained) */
struct list redirect_rules; /* content redirecting rules (chained) */
struct list switching_rules; /* content switching rules (chained) */
struct list persist_rules; /* 'force-persist' and 'ignore-persist' rules (chained) */
struct list sticking_rules; /* content sticking rules (chained) */
struct list storersp_rules; /* content store response rules (chained) */
struct list server_rules; /* server switching rules (chained) */
struct { /* TCP request processing */
unsigned int inspect_delay; /* inspection delay */
struct list inspect_rules; /* inspection rules */
struct list l4_rules; /* layer4 rules */
} tcp_req;
struct { /* TCP request processing */
unsigned int inspect_delay; /* inspection delay */
struct list inspect_rules; /* inspection rules */
} tcp_rep;
...
}
其中, 函数 http_process_req_common 中处理的规则如下:
http_process_req_common
{
...
1. process block rules
...
2. process http req rules
...
3. execute regular exp if any
...
4. req add
...
5. process redirect rules
...
}
这里没有详细的介绍各种具体用途的 rules。随后具体分析代码的时候总结一下再加上。