REORG/MINOR: use dedicated proxy flags for the cookie handling
Cookies were mixed with many other options while they're not used as options.
Move them to a dedicated bitmask (ck_opts). This has released 7 flags in the
proxy options and leaves some room for new proxy flags.
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 15ed23a..2cbf075 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -73,18 +73,13 @@
/* bits for proxy->options */
#define PR_O_REDISP 0x00000001 /* allow reconnection to dispatch in case of errors */
#define PR_O_TRANSP 0x00000002 /* transparent mode : use original DEST as dispatch */
-#define PR_O_COOK_RW 0x00000004 /* rewrite all direct cookies with the right serverid */
-#define PR_O_COOK_IND 0x00000008 /* keep only indirect cookies */
-#define PR_O_COOK_INS 0x00000010 /* insert cookies when not accessing a server directly */
-#define PR_O_COOK_PFX 0x00000020 /* rewrite all cookies by prefixing the right serverid */
-#define PR_O_COOK_ANY (PR_O_COOK_RW | PR_O_COOK_IND | PR_O_COOK_INS | PR_O_COOK_PFX)
+/* unused: 0x04, 0x08, 0x10, 0x20 */
#define PR_O_DISPATCH 0x00000040 /* use dispatch mode */
#define PR_O_KEEPALIVE 0x00000080 /* follow keep-alive sessions */
#define PR_O_FWDFOR 0x00000100 /* conditionally insert x-forwarded-for with client address */
#define PR_O_BIND_SRC 0x00000200 /* bind to a specific source address when connect()ing */
#define PR_O_NULLNOLOG 0x00000400 /* a connect without request will not be logged */
-#define PR_O_COOK_NOC 0x00000800 /* add a 'Cache-control' header with the cookie */
-#define PR_O_COOK_POST 0x00001000 /* don't insert cookies for requests other than a POST */
+/* unused: 0x0800, 0x1000 */
#define PR_O_FF_ALWAYS 0x00002000 /* always set x-forwarded-for */
#define PR_O_PERSIST 0x00004000 /* server persistence stays effective even when server is down */
#define PR_O_LOGASAP 0x00008000 /* log as soon as possible, without waiting for the session to complete */
@@ -150,7 +145,7 @@
#define PR_O2_EXP_RSTR 0x02000000 /* http-check expect rstring */
#define PR_O2_EXP_TYPE 0x03800000 /* mask for http-check expect type */
#define PR_O2_EXP_INV 0x04000000 /* http-check expect !<rule> */
-#define PR_O2_COOK_PSV 0x08000000 /* cookie ... preserve */
+/* unused: 0x08000000 */
/* server health checks */
#define PR_O2_CHK_NONE 0x00000000 /* no L7 health checks configured (TCP by default) */
@@ -165,6 +160,16 @@
#define PR_O2_CHK_ANY 0xF0000000 /* Mask to cover any check */
/* end of proxy->options2 */
+/* Cookie settings for pr->ck_opts */
+#define PR_CK_RW 0x00000001 /* rewrite all direct cookies with the right serverid */
+#define PR_CK_IND 0x00000002 /* keep only indirect cookies */
+#define PR_CK_INS 0x00000004 /* insert cookies when not accessing a server directly */
+#define PR_CK_PFX 0x00000008 /* rewrite all cookies by prefixing the right serverid */
+#define PR_CK_ANY (PR_CK_RW | PR_CK_IND | PR_CK_INS | PR_CK_PFX)
+#define PR_CK_NOC 0x00000010 /* add a 'Cache-control' header with the cookie */
+#define PR_CK_POST 0x00000020 /* don't insert cookies for requests other than a POST */
+#define PR_CK_PSV 0x00000040 /* cookie ... preserve */
+
/* bits for sticking rules */
#define STK_IS_MATCH 0x00000001 /* match on request fetch */
#define STK_IS_STORE 0x00000002 /* store on request fetch */
@@ -198,6 +203,7 @@
int state; /* proxy state */
int options; /* PR_O_REDISP, PR_O_TRANSP, ... */
int options2; /* PR_O2_* */
+ unsigned int ck_opts; /* PR_CK_* (cookie options) */
unsigned int fe_req_ana, be_req_ana; /* bitmap of common request protocol analysers for the frontend and backend */
unsigned int fe_rsp_ana, be_rsp_ana; /* bitmap of common response protocol analysers for the frontend and backend */
int mode; /* mode = PR_MODE_TCP, PR_MODE_HTTP or PR_MODE_HEALTH */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index fe39894..93783ab 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1489,6 +1489,7 @@
}
}
+ curproxy->ck_opts = defproxy.ck_opts;
if (defproxy.cookie_name)
curproxy->cookie_name = strdup(defproxy.cookie_name);
curproxy->cookie_len = defproxy.cookie_len;
@@ -2130,8 +2131,7 @@
goto out;
}
- curproxy->options &= ~PR_O_COOK_ANY;
- curproxy->options2 &= ~PR_O2_COOK_PSV;
+ curproxy->ck_opts = 0;
curproxy->cookie_maxidle = curproxy->cookie_maxlife = 0;
free(curproxy->cookie_domain); curproxy->cookie_domain = NULL;
free(curproxy->cookie_name);
@@ -2141,25 +2141,25 @@
cur_arg = 2;
while (*(args[cur_arg])) {
if (!strcmp(args[cur_arg], "rewrite")) {
- curproxy->options |= PR_O_COOK_RW;
+ curproxy->ck_opts |= PR_CK_RW;
}
else if (!strcmp(args[cur_arg], "indirect")) {
- curproxy->options |= PR_O_COOK_IND;
+ curproxy->ck_opts |= PR_CK_IND;
}
else if (!strcmp(args[cur_arg], "insert")) {
- curproxy->options |= PR_O_COOK_INS;
+ curproxy->ck_opts |= PR_CK_INS;
}
else if (!strcmp(args[cur_arg], "nocache")) {
- curproxy->options |= PR_O_COOK_NOC;
+ curproxy->ck_opts |= PR_CK_NOC;
}
else if (!strcmp(args[cur_arg], "postonly")) {
- curproxy->options |= PR_O_COOK_POST;
+ curproxy->ck_opts |= PR_CK_POST;
}
else if (!strcmp(args[cur_arg], "preserve")) {
- curproxy->options2 |= PR_O2_COOK_PSV;
+ curproxy->ck_opts |= PR_CK_PSV;
}
else if (!strcmp(args[cur_arg], "prefix")) {
- curproxy->options |= PR_O_COOK_PFX;
+ curproxy->ck_opts |= PR_CK_PFX;
}
else if (!strcmp(args[cur_arg], "domain")) {
if (!*args[cur_arg + 1]) {
@@ -2253,19 +2253,19 @@
}
cur_arg++;
}
- if (!POWEROF2(curproxy->options & (PR_O_COOK_RW|PR_O_COOK_IND))) {
+ if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_IND))) {
Alert("parsing [%s:%d] : cookie 'rewrite' and 'indirect' modes are incompatible.\n",
file, linenum);
err_code |= ERR_ALERT | ERR_FATAL;
}
- if (!POWEROF2(curproxy->options & (PR_O_COOK_RW|PR_O_COOK_INS|PR_O_COOK_PFX))) {
+ if (!POWEROF2(curproxy->ck_opts & (PR_CK_RW|PR_CK_INS|PR_CK_PFX))) {
Alert("parsing [%s:%d] : cookie 'rewrite', 'insert' and 'prefix' modes are incompatible.\n",
file, linenum);
err_code |= ERR_ALERT | ERR_FATAL;
}
- if ((curproxy->options2 & PR_O2_COOK_PSV) && !(curproxy->options & (PR_O_COOK_INS|PR_O_COOK_IND))) {
+ if ((curproxy->ck_opts & (PR_CK_PSV | PR_CK_INS | PR_CK_IND)) == PR_CK_PSV) {
Alert("parsing [%s:%d] : cookie 'preserve' requires at least 'insert' or 'indirect'.\n",
file, linenum);
err_code |= ERR_ALERT | ERR_FATAL;
@@ -6410,7 +6410,7 @@
if (curproxy->mode != PR_MODE_HTTP) {
int optnum;
- if (curproxy->options & PR_O_COOK_ANY) {
+ if (curproxy->ck_opts) {
Warning("config : 'cookie' statement ignored for %s '%s' as it requires HTTP mode.\n",
proxy_type_str(curproxy), curproxy->id);
err_code |= ERR_WARN;
diff --git a/src/log.c b/src/log.c
index 74af1c6..15035ae 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1091,8 +1091,8 @@
case LOG_FMT_TERMSTATE_CK: // %tsc, same as TS with cookie state (for mode HTTP)
LOGCHAR(sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT]);
LOGCHAR(sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT]);
- LOGCHAR((be->options & PR_O_COOK_ANY) ? sess_cookie[(txn->flags & TX_CK_MASK) >> TX_CK_SHIFT] : '-');
- LOGCHAR((be->options & PR_O_COOK_ANY) ? sess_set_cookie[(txn->flags & TX_SCK_MASK) >> TX_SCK_SHIFT] : '-');
+ LOGCHAR((be->ck_opts & PR_CK_ANY) ? sess_cookie[(txn->flags & TX_CK_MASK) >> TX_CK_SHIFT] : '-');
+ LOGCHAR((be->ck_opts & PR_CK_ANY) ? sess_set_cookie[(txn->flags & TX_SCK_MASK) >> TX_SCK_SHIFT] : '-');
last_isspace = 0;
break;
diff --git a/src/proto_http.c b/src/proto_http.c
index 4586016..02537ff 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -4715,7 +4715,7 @@
* Cache-Control or Expires header fields."
*/
if (likely(txn->meth != HTTP_METH_POST) &&
- (s->be->options & (PR_O_CHK_CACHE|PR_O_COOK_NOC)))
+ ((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC)))
txn->flags |= TX_CACHEABLE | TX_CACHE_COOK;
break;
default:
@@ -5034,20 +5034,20 @@
/*
* 5: check for cache-control or pragma headers if required.
*/
- if ((t->be->options & (PR_O_COOK_NOC | PR_O_CHK_CACHE)) != 0)
+ if ((t->be->options & PR_O_CHK_CACHE) || (t->be->ck_opts & PR_CK_NOC))
check_response_for_cacheability(t, rep);
/*
* 6: add server cookie in the response if needed
*/
- if (target_srv(&t->target) && (t->be->options & PR_O_COOK_INS) &&
- !((txn->flags & TX_SCK_FOUND) && (t->be->options2 & PR_O2_COOK_PSV)) &&
+ if (target_srv(&t->target) && (t->be->ck_opts & PR_CK_INS) &&
+ !((txn->flags & TX_SCK_FOUND) && (t->be->ck_opts & PR_CK_PSV)) &&
(!(t->flags & SN_DIRECT) ||
((t->be->cookie_maxidle || txn->cookie_last_date) &&
(!txn->cookie_last_date || (txn->cookie_last_date - date.tv_sec) < 0)) ||
(t->be->cookie_maxlife && !txn->cookie_first_date) || // set the first_date
(!t->be->cookie_maxlife && txn->cookie_first_date)) && // remove the first_date
- (!(t->be->options & PR_O_COOK_POST) || (txn->meth == HTTP_METH_POST)) &&
+ (!(t->be->ck_opts & PR_CK_POST) || (txn->meth == HTTP_METH_POST)) &&
!(t->flags & SN_IGNORE_PRST)) {
int len;
/* the server is known, it's not the one the client requested, or the
@@ -5100,7 +5100,7 @@
* Some caches understand the correct form: 'no-cache="set-cookie"', but
* others don't (eg: apache <= 1.3.26). So we use 'private' instead.
*/
- if ((t->be->options & PR_O_COOK_NOC) && (txn->flags & TX_CACHEABLE)) {
+ if ((t->be->ck_opts & PR_CK_NOC) && (txn->flags & TX_CACHEABLE)) {
txn->flags &= ~TX_CACHEABLE & ~TX_CACHE_COOK;
@@ -6127,7 +6127,7 @@
* +-------------------------> hdr_beg
*/
- if (t->be->options & PR_O_COOK_PFX) {
+ if (t->be->ck_opts & PR_CK_PFX) {
for (delim = val_beg; delim < val_end; delim++)
if (*delim == COOKIE_DELIM)
break;
@@ -6241,7 +6241,7 @@
* application cookie so that it does not get accidentely removed later,
* if we're in cookie prefix mode
*/
- if ((t->be->options & PR_O_COOK_PFX) && (delim != val_end)) {
+ if ((t->be->ck_opts & PR_CK_PFX) && (delim != val_end)) {
int delta; /* negative */
delta = buffer_replace2(req, val_beg, delim + 1, NULL, 0);
@@ -6256,7 +6256,7 @@
preserve_hdr = 1; /* we want to keep this cookie */
}
else if (del_from == NULL &&
- (t->be->options & (PR_O_COOK_INS | PR_O_COOK_IND)) == (PR_O_COOK_INS | PR_O_COOK_IND)) {
+ (t->be->ck_opts & (PR_CK_INS | PR_CK_IND)) == (PR_CK_INS | PR_CK_IND)) {
del_from = prev;
}
} else {
@@ -6801,13 +6801,13 @@
* We'll delete it too if the "indirect" option is set and we're in
* a direct access.
*/
- if (t->be->options2 & PR_O2_COOK_PSV) {
+ if (t->be->ck_opts & PR_CK_PSV) {
/* The "preserve" flag was set, we don't want to touch the
* server's cookie.
*/
}
- else if ((srv && (t->be->options & PR_O_COOK_INS)) ||
- ((t->flags & SN_DIRECT) && (t->be->options & PR_O_COOK_IND))) {
+ else if ((srv && (t->be->ck_opts & PR_CK_INS)) ||
+ ((t->flags & SN_DIRECT) && (t->be->ck_opts & PR_CK_IND))) {
/* this cookie must be deleted */
if (*prev == ':' && next == hdr_end) {
/* whole header */
@@ -6834,7 +6834,7 @@
txn->flags |= TX_SCK_DELETED;
/* and go on with next cookie */
}
- else if (srv && srv->cookie && (t->be->options & PR_O_COOK_RW)) {
+ else if (srv && srv->cookie && (t->be->ck_opts & PR_CK_RW)) {
/* replace bytes val_beg->val_end with the cookie name associated
* with this server since we know it.
*/
@@ -6848,7 +6848,7 @@
txn->flags &= ~TX_SCK_MASK;
txn->flags |= TX_SCK_REPLACED;
}
- else if (srv && srv && (t->be->options & PR_O_COOK_PFX)) {
+ else if (srv && srv && (t->be->ck_opts & PR_CK_PFX)) {
/* insert the cookie name associated with this server
* before existing cookie, and insert a delimiter between them..
*/