From b4c8493a9f0177689646670b035d095be6f38891 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 23 Jul 2013 19:15:30 +0200 Subject: [PATCH] MINOR: session: make the number of stick counter entries more configurable In preparation of more flexibility in the stick counters, make their number configurable. It still defaults to 3 which is the minimum accepted value. Changing the value alone is not sufficient to get more counters, some bitfields still need to be updated and the TCP actions need to be updated as well, but this update tries to be easier, which is nice for experimentation purposes. --- include/common/defaults.h | 7 +++++++ include/proto/session.h | 10 +++++----- include/types/proto_tcp.h | 3 ++- include/types/session.h | 6 ++++-- src/cfgparse.c | 4 ++-- src/proto_tcp.c | 14 ++++++++------ src/session.c | 6 +++--- 7 files changed, 31 insertions(+), 19 deletions(-) diff --git a/include/common/defaults.h b/include/common/defaults.h index 5000d9c3d..874d2e273 100644 --- a/include/common/defaults.h +++ b/include/common/defaults.h @@ -73,6 +73,13 @@ #define MAX_HDR_HISTORY 10 #endif +// max # of stick counters per session (at least 3 for sc0..sc2) +// Some changes are needed in TCP_ACT_TRK_SC* and SN_BE_TRACK_SC* if more +// values are required. +#ifndef MAX_SESS_STKCTR +#define MAX_SESS_STKCTR 3 +#endif + // max # of loops we can perform around a read() which succeeds. // It's very frequent that the system returns a few TCP segments at a time. #ifndef MAX_READ_POLL_LOOPS diff --git a/include/proto/session.h b/include/proto/session.h index cc1242daa..f597d5977 100644 --- a/include/proto/session.h +++ b/include/proto/session.h @@ -59,7 +59,7 @@ static inline void session_store_counters(struct session *s) void *ptr; int i; - for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) { + for (i = 0; i < MAX_SESS_STKCTR; i++) { if (!s->stkctr[i].entry) continue; ptr = stktable_data_ptr(s->stkctr[i].table, s->stkctr[i].entry, STKTABLE_DT_CONN_CUR); @@ -83,7 +83,7 @@ static inline void session_stop_backend_counters(struct session *s) if (likely(!(s->flags & SN_BE_TRACK_ANY))) return; - for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) { + for (i = 0; i < MAX_SESS_STKCTR; i++) { if (!s->stkctr[i].entry) continue; @@ -145,7 +145,7 @@ static void inline session_inc_http_req_ctr(struct session *s) void *ptr; int i; - for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) { + for (i = 0; i < MAX_SESS_STKCTR; i++) { if (!s->stkctr[i].entry) continue; @@ -169,7 +169,7 @@ static void inline session_inc_be_http_req_ctr(struct session *s) if (likely(!(s->flags & SN_BE_TRACK_ANY))) return; - for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) { + for (i = 0; i < MAX_SESS_STKCTR; i++) { if (!s->stkctr[i].entry) continue; @@ -198,7 +198,7 @@ static void inline session_inc_http_err_ctr(struct session *s) void *ptr; int i; - for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) { + for (i = 0; i < MAX_SESS_STKCTR; i++) { if (!s->stkctr[i].entry) continue; diff --git a/include/types/proto_tcp.h b/include/types/proto_tcp.h index a820462cf..662cde495 100644 --- a/include/types/proto_tcp.h +++ b/include/types/proto_tcp.h @@ -33,9 +33,10 @@ enum { TCP_ACT_ACCEPT = 1, TCP_ACT_REJECT = 2, TCP_ACT_EXPECT_PX = 3, - TCP_ACT_TRK_SC0 = 4, /* TCP request tracking : must be contiguous */ + TCP_ACT_TRK_SC0 = 4, /* TCP request tracking : must be contiguous and cover up to MAX_SESS_STKCTR values */ TCP_ACT_TRK_SC1 = 5, TCP_ACT_TRK_SC2 = 6, + TCP_ACT_TRK_SCMAX = TCP_ACT_TRK_SC0 + MAX_SESS_STKCTR - 1, }; struct tcp_rule { diff --git a/include/types/session.h b/include/types/session.h index 42d37dbed..8f731ddee 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -90,7 +90,9 @@ #define SN_COMP_READY 0x00100000 /* the compression is initialized */ -/* session tracking flags: these ones must absolutely be contiguous. See also s->stkctr */ +/* session tracking flags: these ones must absolutely be contiguous and cover + * at least MAX_SESS_STKCTR flags. + */ #define SN_BE_TRACK_SC0 0x00200000 /* backend tracks stick-counter 0 */ #define SN_BE_TRACK_SC1 0x00400000 /* backend tracks stick-counter 1 */ #define SN_BE_TRACK_SC2 0x00800000 /* backend tracks stick-counter 2 */ @@ -146,7 +148,7 @@ struct session { } store[8]; /* tracked stickiness values to store */ int store_count; - struct stkctr stkctr[3]; /* stick counters */ + struct stkctr stkctr[MAX_SESS_STKCTR]; /* stick counters */ struct stream_interface si[2]; /* client and server stream interfaces */ struct { diff --git a/src/cfgparse.c b/src/cfgparse.c index a85bbedf0..d51e1b6da 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -6367,7 +6367,7 @@ int check_config_validity() list_for_each_entry(trule, &curproxy->tcp_req.l4_rules, list) { struct proxy *target; - if (trule->action < TCP_ACT_TRK_SC0 || trule->action > TCP_ACT_TRK_SC2) + if (trule->action < TCP_ACT_TRK_SC0 || trule->action > TCP_ACT_TRK_SCMAX) continue; if (trule->act_prm.trk_ctr.table.n) @@ -6406,7 +6406,7 @@ int check_config_validity() list_for_each_entry(trule, &curproxy->tcp_req.inspect_rules, list) { struct proxy *target; - if (trule->action < TCP_ACT_TRK_SC0 || trule->action > TCP_ACT_TRK_SC2) + if (trule->action < TCP_ACT_TRK_SC0 || trule->action > TCP_ACT_TRK_SCMAX) continue; if (trule->act_prm.trk_ctr.table.n) diff --git a/src/proto_tcp.c b/src/proto_tcp.c index fe4a0d2b5..797f3357e 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -938,7 +938,7 @@ int tcp_inspect_request(struct session *s, struct channel *req, int an_bit) s->flags |= SN_FINST_R; return 0; } - else if ((rule->action >= TCP_ACT_TRK_SC0 && rule->action <= TCP_ACT_TRK_SC2) && + else if ((rule->action >= TCP_ACT_TRK_SC0 && rule->action <= TCP_ACT_TRK_SCMAX) && !s->stkctr[tcp_trk_idx(rule->action)].entry) { /* Note: only the first valid tracking parameter of each * applies. @@ -1092,7 +1092,7 @@ int tcp_exec_req_rules(struct session *s) result = 0; break; } - else if ((rule->action >= TCP_ACT_TRK_SC0 && rule->action <= TCP_ACT_TRK_SC2) && + else if ((rule->action >= TCP_ACT_TRK_SC0 && rule->action <= TCP_ACT_TRK_SCMAX) && !s->stkctr[tcp_trk_idx(rule->action)].entry) { /* Note: only the first valid tracking parameter of each * applies. @@ -1184,7 +1184,9 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type, arg++; rule->action = TCP_ACT_REJECT; } - else if (strcmp(args[arg], "track-sc0") == 0 || strcmp(args[arg], "track-sc1") == 0 || strcmp(args[arg], "track-sc2") == 0) { + else if (strncmp(args[arg], "track-sc", 8) == 0 && + args[arg][9] == '\0' && args[arg][8] >= '0' && + args[arg][8] <= '0' + MAX_SESS_STKCTR) { /* track-sc 0..9 */ struct sample_expr *expr; int kw = arg; @@ -1246,9 +1248,9 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type, } else { memprintf(err, - "'%s %s' expects 'accept', 'reject', 'track-sc0', 'track-sc1' " - " or 'track-sc2' in %s '%s' (got '%s')", - args[0], args[1], proxy_type_str(curpx), curpx->id, args[arg]); + "'%s %s' expects 'accept', 'reject', 'track-sc0' ... 'track-sc%d' " + " in %s '%s' (got '%s')", + args[0], args[1], MAX_SESS_STKCTR, proxy_type_str(curpx), curpx->id, args[arg]); return -1; } diff --git a/src/session.c b/src/session.c index 9be5faa21..ec78be1b3 100644 --- a/src/session.c +++ b/src/session.c @@ -420,7 +420,7 @@ int session_complete(struct session *s) /* Let's count a session now */ proxy_inc_fe_sess_ctr(l, p); - for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) { + for (i = 0; i < MAX_SESS_STKCTR; i++) { void *ptr; if (!s->stkctr[i].entry) @@ -707,7 +707,7 @@ void session_process_counters(struct session *s) if (s->listener->counters) s->listener->counters->bytes_in += bytes; - for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) { + for (i = 0; i < MAX_SESS_STKCTR; i++) { if (!s->stkctr[i].entry) continue; @@ -741,7 +741,7 @@ void session_process_counters(struct session *s) if (s->listener->counters) s->listener->counters->bytes_out += bytes; - for (i = 0; i < sizeof(s->stkctr) / sizeof(s->stkctr[0]); i++) { + for (i = 0; i < MAX_SESS_STKCTR; i++) { if (!s->stkctr[i].entry) continue;