return static_table_key;
}
+/* for a tcp-request action TCP_ACT_TRK_*, return a tracking index starting at
+ * zero for SC1. Unknown actions also return zero.
+ */
+static inline int tcp_trk_idx(int trk_action)
+{
+ return trk_action - TCP_ACT_TRK_SC1;
+}
#endif /* _PROTO_PROTO_TCP_H */
void *ptr;
int i;
- if (!(s->flags & (SN_BE_TRACK_SC1|SN_BE_TRACK_SC2)))
+ if (likely(!(s->flags & SN_BE_TRACK_ANY)))
return;
for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) {
if (!s->stkctr[i].entry)
continue;
- if ((i == 0) && !(s->flags & SN_BE_TRACK_SC1))
- continue;
-
- if ((i == 1) && !(s->flags & SN_BE_TRACK_SC2))
+ if (!(s->flags & (SN_BE_TRACK_SC1 << i)))
continue;
ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_CONN_CUR);
stksess_kill_if_expired(s->stkctr[i].table, s->stkctr[i].entry);
s->stkctr[i].entry = NULL;
}
- s->flags &= ~(SN_BE_TRACK_SC1|SN_BE_TRACK_SC2);
+ s->flags &= ~SN_BE_TRACK_ANY;
}
/* Increase total and concurrent connection count for stick entry <ts> of table
void *ptr;
int i;
- if (likely(!(s->flags & (SN_BE_TRACK_SC1|SN_BE_TRACK_SC2))))
+ if (likely(!(s->flags & SN_BE_TRACK_ANY)))
return;
for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) {
if (!s->stkctr[i].entry)
continue;
- if ((i == 0) && !(s->flags & SN_BE_TRACK_SC1))
- continue;
-
- if ((i == 1) && !(s->flags & SN_BE_TRACK_SC2))
+ if (!(s->flags & (SN_BE_TRACK_SC1 << i)))
continue;
ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_HTTP_REQ_CNT);
enum {
TCP_ACT_ACCEPT = 1,
TCP_ACT_REJECT = 2,
- TCP_ACT_TRK_SC1 = 3,
+ TCP_ACT_TRK_SC1 = 3, /* TCP request tracking : must be contiguous */
TCP_ACT_TRK_SC2 = 4,
};
#define SN_FINST_SHIFT 16 /* bit shift */
#define SN_IGNORE_PRST 0x00080000 /* ignore persistence */
-#define SN_BE_TRACK_SC1 0x00100000 /* backend tracks stick-counter 1 */
-#define SN_BE_TRACK_SC2 0x00200000 /* backend tracks stick-counter 2 */
-#define SN_COMP_READY 0x00400000 /* the compression is initialized */
+#define SN_COMP_READY 0x00100000 /* the compression is initialized */
+
+/* session tracking flags: these ones must absolutely be contiguous */
+#define SN_BE_TRACK_SC1 0x00200000 /* backend tracks stick-counter 1 */
+#define SN_BE_TRACK_SC2 0x00400000 /* backend tracks stick-counter 2 */
+#define SN_BE_TRACK_ANY 0x00600000 /* union of all SN_BE_TRACK_* above */
/* WARNING: if new fields are added, they must be initialized in event_accept()
list_for_each_entry(trule, &curproxy->tcp_req.l4_rules, list) {
struct proxy *target;
- if (trule->action != TCP_ACT_TRK_SC1 && trule->action != TCP_ACT_TRK_SC2)
+ if (trule->action < TCP_ACT_TRK_SC1 || trule->action > TCP_ACT_TRK_SC2)
continue;
if (trule->act_prm.trk_ctr.table.n)
if (!target) {
Alert("Proxy '%s': unable to find table '%s' referenced by track-sc%d.\n",
curproxy->id, trule->act_prm.trk_ctr.table.n,
- trule->action == TCP_ACT_TRK_SC1 ? 1 : 2);
+ 1 + tcp_trk_idx(trule->action));
cfgerr++;
}
else if (target->table.size == 0) {
else if (!stktable_compatible_sample(trule->act_prm.trk_ctr.expr, target->table.type)) {
Alert("Proxy '%s': stick-table '%s' uses a type incompatible with the 'track-sc%d' rule.\n",
curproxy->id, trule->act_prm.trk_ctr.table.n ? trule->act_prm.trk_ctr.table.n : curproxy->id,
- trule->action == TCP_ACT_TRK_SC1 ? 1 : 2);
+ 1 + tcp_trk_idx(trule->action));
cfgerr++;
}
else {
list_for_each_entry(trule, &curproxy->tcp_req.inspect_rules, list) {
struct proxy *target;
- if (trule->action != TCP_ACT_TRK_SC1 && trule->action != TCP_ACT_TRK_SC2)
+ if (trule->action < TCP_ACT_TRK_SC1 || trule->action > TCP_ACT_TRK_SC2)
continue;
if (trule->act_prm.trk_ctr.table.n)
if (!target) {
Alert("Proxy '%s': unable to find table '%s' referenced by track-sc%d.\n",
curproxy->id, trule->act_prm.trk_ctr.table.n,
- trule->action == TCP_ACT_TRK_SC1 ? 1 : 2);
+ 1 + tcp_trk_idx(trule->action));
cfgerr++;
}
else if (target->table.size == 0) {
else if (!stktable_compatible_sample(trule->act_prm.trk_ctr.expr, target->table.type)) {
Alert("Proxy '%s': stick-table '%s' uses a type incompatible with the 'track-sc%d' rule.\n",
curproxy->id, trule->act_prm.trk_ctr.table.n ? trule->act_prm.trk_ctr.table.n : curproxy->id,
- trule->action == TCP_ACT_TRK_SC1 ? 1 : 2);
+ 1 + tcp_trk_idx(trule->action));
cfgerr++;
}
else {
/* init store persistence */
s->store_count = 0;
- s->stkctr[0].entry = NULL;
- s->stkctr[1].entry = NULL;
+ memset(s->stkctr, 0, sizeof(s->stkctr));
/* FIXME: the logs are horribly complicated now, because they are
* defined in <p>, <p>, and later <be> and <be>.
s->flags |= SN_FINST_R;
return 0;
}
- else if ((rule->action == TCP_ACT_TRK_SC1 && !s->stkctr[0].entry) ||
- (rule->action == TCP_ACT_TRK_SC2 && !s->stkctr[1].entry)) {
+ else if ((rule->action >= TCP_ACT_TRK_SC1 && rule->action <= TCP_ACT_TRK_SC2) &&
+ !s->stkctr[tcp_trk_idx(rule->action)].entry) {
/* Note: only the first valid tracking parameter of each
* applies.
*/
key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->act_prm.trk_ctr.expr);
if (key && (ts = stktable_get_entry(t, key))) {
- if (rule->action == TCP_ACT_TRK_SC1) {
- session_track_stkctr(&s->stkctr[0], t, ts);
- if (s->fe != s->be)
- s->flags |= SN_BE_TRACK_SC1;
- } else {
- session_track_stkctr(&s->stkctr[1], t, ts);
- if (s->fe != s->be)
- s->flags |= SN_BE_TRACK_SC2;
- }
+ session_track_stkctr(&s->stkctr[tcp_trk_idx(rule->action)], t, ts);
+ if (s->fe != s->be)
+ s->flags |= SN_BE_TRACK_SC1 << tcp_trk_idx(rule->action);
}
}
else {
result = 0;
break;
}
- else if ((rule->action == TCP_ACT_TRK_SC1 && !s->stkctr[0].entry) ||
- (rule->action == TCP_ACT_TRK_SC2 && !s->stkctr[1].entry)) {
+ else if ((rule->action >= TCP_ACT_TRK_SC1 && rule->action <= TCP_ACT_TRK_SC2) &&
+ !s->stkctr[tcp_trk_idx(rule->action)].entry) {
/* Note: only the first valid tracking parameter of each
* applies.
*/
t = rule->act_prm.trk_ctr.table.t;
key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->act_prm.trk_ctr.expr);
- if (key && (ts = stktable_get_entry(t, key))) {
- if (rule->action == TCP_ACT_TRK_SC1)
- session_track_stkctr(&s->stkctr[0], t, ts);
- else
- session_track_stkctr(&s->stkctr[1], t, ts);
- }
+ if (key && (ts = stktable_get_entry(t, key)))
+ session_track_stkctr(&s->stkctr[tcp_trk_idx(rule->action)], t, ts);
}
else {
/* otherwise it's an accept */
arg++;
}
rule->act_prm.trk_ctr.expr = expr;
-
- if (args[kw][8] == '1')
- rule->action = TCP_ACT_TRK_SC1;
- else
- rule->action = TCP_ACT_TRK_SC2;
+ rule->action = TCP_ACT_TRK_SC1 + args[kw][8] - '1';
}
else {
memprintf(err,
*/
s->flags = 0;
s->logs.logwait = p->to_log;
- s->stkctr[0].entry = NULL;
- s->stkctr[1].entry = NULL;
- s->stkctr[0].table = NULL;
- s->stkctr[1].table = NULL;
+
+ memset(s->stkctr, 0, sizeof(s->stkctr));
s->listener = l;
s->fe = p;