diff --git a/include/types/backend.h b/include/types/backend.h index a71db6912..536f453d6 100644 --- a/include/types/backend.h +++ b/include/types/backend.h @@ -24,53 +24,14 @@ #include -/* 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) -#define PR_O_SMTP_CHK 0x00000040 /* use SMTP EHLO check for server health - pvandijk@vision6.com.au */ -#define PR_O_KEEPALIVE 0x00000080 /* follow keep-alive sessions */ -#define PR_O_FWDFOR 0x00000100 /* 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 */ -#define PR_O_HTTP_CHK 0x00002000 /* use HTTP 'OPTIONS' method to check server health */ -#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 */ -#define PR_O_HTTP_CLOSE 0x00010000 /* force 'connection: close' in both directions */ -#define PR_O_CHK_CACHE 0x00020000 /* require examination of cacheability of the 'set-cookie' field */ -#define PR_O_TCP_CLI_KA 0x00040000 /* enable TCP keep-alive on client-side sessions */ -#define PR_O_TCP_SRV_KA 0x00080000 /* enable TCP keep-alive on server-side sessions */ -#define PR_O_USE_ALL_BK 0x00100000 /* load-balance between backup servers */ -#define PR_O_FORCE_CLO 0x00200000 /* enforce the connection close immediately after server response */ -#define PR_O_TCP_NOLING 0x00400000 /* disable lingering on client and server connections */ -#define PR_O_ABRT_CLOSE 0x00800000 /* immediately abort request when client closes */ -#define PR_O_SSL3_CHK 0x01000000 /* use SSLv3 CLIENT_HELLO packets for server health */ - -/* TPXY: exclusive values */ -#define PR_O_TPXY_ADDR 0x02000000 /* bind to this non-local address when connect()ing */ -#define PR_O_TPXY_CIP 0x04000000 /* bind to the client's IP address when connect()ing */ -#define PR_O_TPXY_CLI 0x06000000 /* bind to the client's IP+port when connect()ing */ -#define PR_O_TPXY_MASK 0x06000000 /* bind to a non-local address when connect()ing */ - -#define PR_O_TCPSPLICE 0x08000000 /* delegate data transfer to linux kernel's tcp_splice */ - -/* BALANCE: exclusive values */ -#define PR_O_BALANCE_RR 0x10000000 /* balance in round-robin mode */ -#define PR_O_BALANCE_SH 0x20000000 /* balance on source IP hash */ -#define PR_O_BALANCE_L4 0x30000000 /* mask to match layer4-based algorithms */ -#define PR_O_BALANCE_UH 0x40000000 /* balance on URI hash */ -#define PR_O_BALANCE_PH 0x50000000 /* balance on URL parameter hash */ -#define PR_O_BALANCE_L7 0x40000000 /* mask to match layer7-based algorithms */ -#define PR_O_BALANCE 0x70000000 /* mask to extract BALANCE algorithm */ - -#define PR_O_CONTSTATS 0x80000000 /* continous counters */ - +/* Parameters for proxy->lbprm.algo. Those values are exclusive */ +#define BE_LB_ALGO_RR 0x00000001 /* balance in round-robin mode */ +#define BE_LB_ALGO_SH 0x00000002 /* balance on source IP hash */ +#define BE_LB_ALGO_L4 0x00000003 /* mask to match layer4-based algorithms */ +#define BE_LB_ALGO_UH 0x00000004 /* balance on URI hash */ +#define BE_LB_ALGO_PH 0x00000005 /* balance on URL parameter hash */ +#define BE_LB_ALGO_L7 0x00000004 /* mask to match layer7-based algorithms */ +#define BE_LB_ALGO 0x00000007 /* mask to extract BALANCE algorithm */ /* various constants */ #define BE_WEIGHT_SCALE 256 /* scale between user weight and effective weight */ diff --git a/include/types/proxy.h b/include/types/proxy.h index 6d27a9bff..6ffc264cd 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -65,6 +65,43 @@ #define PR_CAP_RS 0x0004 #define PR_CAP_LISTEN (PR_CAP_FE|PR_CAP_BE|PR_CAP_RS) +/* 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) +#define PR_O_SMTP_CHK 0x00000040 /* use SMTP EHLO check for server health - pvandijk@vision6.com.au */ +#define PR_O_KEEPALIVE 0x00000080 /* follow keep-alive sessions */ +#define PR_O_FWDFOR 0x00000100 /* 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 */ +#define PR_O_HTTP_CHK 0x00002000 /* use HTTP 'OPTIONS' method to check server health */ +#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 */ +#define PR_O_HTTP_CLOSE 0x00010000 /* force 'connection: close' in both directions */ +#define PR_O_CHK_CACHE 0x00020000 /* require examination of cacheability of the 'set-cookie' field */ +#define PR_O_TCP_CLI_KA 0x00040000 /* enable TCP keep-alive on client-side sessions */ +#define PR_O_TCP_SRV_KA 0x00080000 /* enable TCP keep-alive on server-side sessions */ +#define PR_O_USE_ALL_BK 0x00100000 /* load-balance between backup servers */ +#define PR_O_FORCE_CLO 0x00200000 /* enforce the connection close immediately after server response */ +#define PR_O_TCP_NOLING 0x00400000 /* disable lingering on client and server connections */ +#define PR_O_ABRT_CLOSE 0x00800000 /* immediately abort request when client closes */ +#define PR_O_SSL3_CHK 0x01000000 /* use SSLv3 CLIENT_HELLO packets for server health */ + +/* TPXY: exclusive values */ +#define PR_O_TPXY_ADDR 0x02000000 /* bind to this non-local address when connect()ing */ +#define PR_O_TPXY_CIP 0x04000000 /* bind to the client's IP address when connect()ing */ +#define PR_O_TPXY_CLI 0x06000000 /* bind to the client's IP+port when connect()ing */ +#define PR_O_TPXY_MASK 0x06000000 /* bind to a non-local address when connect()ing */ + +#define PR_O_TCPSPLICE 0x08000000 /* delegate data transfer to linux kernel's tcp_splice */ +#define PR_O_CONTSTATS 0x10000000 /* continous counters */ + /* This structure is used to apply fast weighted round robin on a server group */ struct fwrr_group { struct eb_root curr; /* tree for servers in "current" time range */ @@ -94,6 +131,7 @@ struct proxy { int srv_act, srv_bck; /* # of servers eligible for LB (UP|!checked) AND (enabled+weight!=0) */ struct { + int algo; /* load balancing algorithm and variants: BE_LB_ALGO* */ int tot_wact, tot_wbck; /* total effective weights of active and backup servers */ int tot_weight; /* total effective weight of servers participating to LB */ int tot_used; /* total number of servers used for LB */ diff --git a/src/backend.c b/src/backend.c index 9b0f0aa00..91027e817 100644 --- a/src/backend.c +++ b/src/backend.c @@ -85,7 +85,7 @@ static void recount_servers(struct proxy *px) if (srv->state & SRV_BACKUP) { if (!px->srv_bck && - !(px->options & PR_O_USE_ALL_BK)) + !(px->lbprm.algo & PR_O_USE_ALL_BK)) px->lbprm.fbck = srv; px->srv_bck++; px->lbprm.tot_wbck += srv->eweight; @@ -884,7 +884,7 @@ int assign_server(struct session *s) return SRV_STATUS_INTERNAL; if (!(s->flags & SN_ASSIGNED)) { - if (s->be->options & PR_O_BALANCE) { + if (s->be->lbprm.algo & BE_LB_ALGO) { int len; if (s->flags & SN_DIRECT) { @@ -895,13 +895,13 @@ int assign_server(struct session *s) if (!s->be->lbprm.tot_weight) return SRV_STATUS_NOSRV; - switch (s->be->options & PR_O_BALANCE) { - case PR_O_BALANCE_RR: + switch (s->be->lbprm.algo & BE_LB_ALGO) { + case BE_LB_ALGO_RR: s->srv = fwrr_get_next_server(s->be); if (!s->srv) return SRV_STATUS_FULL; break; - case PR_O_BALANCE_SH: + case BE_LB_ALGO_SH: if (s->cli_addr.ss_family == AF_INET) len = 4; else if (s->cli_addr.ss_family == AF_INET6) @@ -913,13 +913,13 @@ int assign_server(struct session *s) (void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr, len); break; - case PR_O_BALANCE_UH: + case BE_LB_ALGO_UH: /* URI hashing */ s->srv = get_server_uh(s->be, s->txn.req.sol + s->txn.req.sl.rq.u, s->txn.req.sl.rq.u_l); break; - case PR_O_BALANCE_PH: + case BE_LB_ALGO_PH: /* URL Parameter hashing */ s->srv = get_server_ph(s->be, s->txn.req.sol + s->txn.req.sl.rq.u, @@ -965,7 +965,7 @@ int assign_server_address(struct session *s) fprintf(stderr,"assign_server_address : s=%p\n",s); #endif - if ((s->flags & SN_DIRECT) || (s->be->options & PR_O_BALANCE)) { + if ((s->flags & SN_DIRECT) || (s->be->lbprm.algo & BE_LB_ALGO)) { /* A server is necessarily known for this session */ if (!(s->flags & SN_ASSIGNED)) return SRV_STATUS_INTERNAL; @@ -1478,30 +1478,30 @@ int backend_parse_balance(const char **args, char *err, int errlen, struct proxy { if (!*(args[0])) { /* if no option is set, use round-robin by default */ - curproxy->options &= ~PR_O_BALANCE; - curproxy->options |= PR_O_BALANCE_RR; + curproxy->lbprm.algo &= ~BE_LB_ALGO; + curproxy->lbprm.algo |= BE_LB_ALGO_RR; return 0; } if (!strcmp(args[0], "roundrobin")) { - curproxy->options &= ~PR_O_BALANCE; - curproxy->options |= PR_O_BALANCE_RR; + curproxy->lbprm.algo &= ~BE_LB_ALGO; + curproxy->lbprm.algo |= BE_LB_ALGO_RR; } else if (!strcmp(args[0], "source")) { - curproxy->options &= ~PR_O_BALANCE; - curproxy->options |= PR_O_BALANCE_SH; + curproxy->lbprm.algo &= ~BE_LB_ALGO; + curproxy->lbprm.algo |= BE_LB_ALGO_SH; } else if (!strcmp(args[0], "uri")) { - curproxy->options &= ~PR_O_BALANCE; - curproxy->options |= PR_O_BALANCE_UH; + curproxy->lbprm.algo &= ~BE_LB_ALGO; + curproxy->lbprm.algo |= BE_LB_ALGO_UH; } else if (!strcmp(args[0], "url_param")) { if (!*args[1]) { snprintf(err, errlen, "'balance url_param' requires an URL parameter name."); return -1; } - curproxy->options &= ~PR_O_BALANCE; - curproxy->options |= PR_O_BALANCE_PH; + curproxy->lbprm.algo &= ~BE_LB_ALGO; + curproxy->lbprm.algo |= BE_LB_ALGO_PH; if (curproxy->url_param_name) free(curproxy->url_param_name); curproxy->url_param_name = strdup(args[1]); diff --git a/src/cfgparse.c b/src/cfgparse.c index d9b2ce6a3..47530120d 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -588,6 +588,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args) /* set default values */ curproxy->state = defproxy.state; curproxy->options = defproxy.options; + curproxy->lbprm.algo = defproxy.lbprm.algo; curproxy->except_net = defproxy.except_net; curproxy->except_mask = defproxy.except_mask; @@ -2472,14 +2473,15 @@ int readcfgfile(const char *file) } else if (curproxy->cap & PR_CAP_BE && ((curproxy->mode != PR_MODE_HEALTH) && - !(curproxy->options & (PR_O_TRANSP | PR_O_BALANCE)) && + !(curproxy->options & PR_O_TRANSP) && + !(curproxy->lbprm.algo & BE_LB_ALGO) && (*(int *)&curproxy->dispatch_addr.sin_addr == 0))) { Alert("parsing %s : %s '%s' has no dispatch address and is not in transparent or balance mode.\n", file, proxy_type_str(curproxy), curproxy->id); cfgerr++; } - if ((curproxy->mode != PR_MODE_HEALTH) && (curproxy->options & PR_O_BALANCE)) { + if ((curproxy->mode != PR_MODE_HEALTH) && (curproxy->lbprm.algo & BE_LB_ALGO)) { if (curproxy->options & PR_O_TRANSP) { Alert("parsing %s : %s '%s' cannot use both transparent and balance mode.\n", file, proxy_type_str(curproxy), curproxy->id); @@ -2515,9 +2517,9 @@ int readcfgfile(const char *file) Warning("parsing %s : monitor-uri will be ignored for %s '%s'.\n", file, proxy_type_str(curproxy), curproxy->id); } - if (curproxy->options & PR_O_BALANCE_L7) { - curproxy->options &= ~PR_O_BALANCE; - curproxy->options |= PR_O_BALANCE_RR; + if (curproxy->lbprm.algo & BE_LB_ALGO_L7) { + curproxy->lbprm.algo &= ~BE_LB_ALGO; + curproxy->lbprm.algo |= BE_LB_ALGO_RR; Warning("parsing %s : Layer 7 hash not possible for %s '%s'. Falling back to round robin.\n", file, proxy_type_str(curproxy), curproxy->id); @@ -2658,7 +2660,7 @@ int readcfgfile(const char *file) curproxy->lbprm.wdiv = 1; /* default weight divider */ /* round robin relies on a weight tree */ - if ((curproxy->options & PR_O_BALANCE) == PR_O_BALANCE_RR) + if ((curproxy->lbprm.algo & BE_LB_ALGO) == BE_LB_ALGO_RR) fwrr_init_server_groups(curproxy); else init_server_map(curproxy);