From: Willy Tarreau Date: Thu, 31 May 2012 18:40:20 +0000 (+0200) Subject: REORG/MINOR: use dedicated proxy flags for the cookie handling X-Git-Tag: v1.5-dev12~158 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=674021329c263683842c3a69133f073c0da5a18c;p=thirdparty%2Fhaproxy.git 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 15ed23af1a..2cbf075a42 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -73,18 +73,13 @@ enum { /* 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 @@ enum { #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 ! */ -#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 @@ enum { #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 @@ struct proxy { 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 fe39894014..93783ab712 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -1489,6 +1489,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) } } + 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 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) 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 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) 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 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) } 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 @@ out_uri_auth_compat: 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 74af1c6804..15035aed16 100644 --- a/src/log.c +++ b/src/log.c @@ -1091,8 +1091,8 @@ int build_logline(struct session *s, char *dst, size_t maxsize, struct list *lis 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 45860164ad..02537ff40a 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -4715,7 +4715,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit) * 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 @@ int http_process_res_common(struct session *t, struct buffer *rep, int an_bit, s /* * 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 @@ int http_process_res_common(struct session *t, struct buffer *rep, int an_bit, s * 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 @@ void manage_client_side_cookies(struct session *t, struct buffer *req) * +-------------------------> 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 @@ void manage_client_side_cookies(struct session *t, struct buffer *req) * 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 @@ void manage_client_side_cookies(struct session *t, struct buffer *req) 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 @@ void manage_server_side_cookies(struct session *t, struct buffer *res) * 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 @@ void manage_server_side_cookies(struct session *t, struct buffer *res) 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 @@ void manage_server_side_cookies(struct session *t, struct buffer *res) 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.. */