#define PR_O_CONTSTATS 0x10000000 /* continous counters */
#define PR_O_HTTP_PROXY 0x20000000 /* Enable session to use HTTP proxy operations */
#define PR_O_DISABLE404 0x40000000 /* Disable a server on a 404 response to a health-check */
+/* unused: 0x80000000 */
+
+/* bits for proxy->options2 */
+#define PR_O2_SPLIC_REQ 0x00000001 /* transfer requests using linux kernel's splice() */
+#define PR_O2_SPLIC_RTR 0x00000002 /* transfer responses using linux kernel's splice() */
+#define PR_O2_SPLIC_AUT 0x00000004 /* automatically use linux kernel's splice() */
+#define PR_O2_SPLIC_ANY (PR_O2_SPLIC_REQ|PR_O2_SPLIC_RTR|PR_O2_SPLIC_AUT)
/* This structure is used to apply fast weighted round robin on a server group */
struct fwrr_group {
struct in_addr mon_net, mon_mask; /* don't forward connections from this net (network order) FIXME: should support IPv6 */
int state; /* proxy state */
int options; /* PR_O_REDISP, PR_O_TRANSP, ... */
+ int options2; /* PR_O2_* */
int mode; /* mode = PR_MODE_TCP, PR_MODE_HTTP or PR_MODE_HEALTH */
struct sockaddr_in dispatch_addr; /* the default address to connect to */
union {
};
/* some of the most common options which are also the easiest to handle */
-static const struct {
+struct cfg_opt {
const char *name;
unsigned int val;
unsigned int cap;
unsigned int checks;
-} cfg_opts[] =
+};
+
+/* proxy->options */
+static const struct cfg_opt cfg_opts[] =
{
{ "abortonclose", PR_O_ABRT_CLOSE, PR_CAP_BE, 0 },
{ "allbackups", PR_O_USE_ALL_BK, PR_CAP_BE, 0 },
{ NULL, 0, 0, 0 }
};
+/* proxy->options2 */
+static const struct cfg_opt cfg_opts2[] =
+{
+#ifdef CONFIG_HAP_LINUX_SPLICE
+ { "splice-request", PR_O2_SPLIC_REQ, PR_CAP_FE|PR_CAP_BE, 0 },
+ { "splice-response", PR_O2_SPLIC_RTR, PR_CAP_FE|PR_CAP_BE, 0 },
+ { "splice-auto", PR_O2_SPLIC_AUT, PR_CAP_FE|PR_CAP_BE, 0 },
+#endif
+ { NULL, 0, 0, 0 }
+};
static char *cursection = NULL;
static struct proxy defproxy; /* fake proxy used to assign default values on all instances */
/* set default values */
curproxy->state = defproxy.state;
curproxy->options = defproxy.options;
+ curproxy->options2 = defproxy.options2;
curproxy->lbprm.algo = defproxy.lbprm.algo;
curproxy->except_net = defproxy.except_net;
curproxy->except_mask = defproxy.except_mask;
}
}
+ for (optnum = 0; cfg_opts2[optnum].name; optnum++) {
+ if (!strcmp(args[1], cfg_opts2[optnum].name)) {
+ if (warnifnotcap(curproxy, cfg_opts2[optnum].cap, file, linenum, args[1], NULL))
+ return 0;
+
+ if (!inv)
+ curproxy->options2 |= cfg_opts2[optnum].val;
+ else
+ curproxy->options2 &= ~cfg_opts2[optnum].val;
+
+ return 0;
+ }
+ }
+
if (inv) {
Alert("parsing [%s:%d]: negation is not supported for option '%s'.\n",
file, linenum, args[1]);
for (curproxy=proxy; curproxy; curproxy=curproxy->next) {
int optnum;
- for (optnum = 0; cfg_opts[optnum].name; optnum++) {
- if (!(curproxy->options & cfg_opts[optnum].val))
- continue;
+ for (optnum = 0; cfg_opts[optnum].name; optnum++)
+ if (curproxy->options & cfg_opts[optnum].val)
+ global.last_checks |= cfg_opts[optnum].checks;
- global.last_checks |= cfg_opts[optnum].checks;
- }
+ for (optnum = 0; cfg_opts2[optnum].name; optnum++)
+ if (curproxy->options2 & cfg_opts2[optnum].val)
+ global.last_checks |= cfg_opts2[optnum].checks;
}
free(cursection);
if (global.maxconn == 0)
global.maxconn = DEFAULT_MAXCONN;
+ if (!global.maxpipes) {
+ /* maxpipes not specified. Count how many frontends and backends
+ * may be using splicing, and bound that to maxconn.
+ */
+ struct proxy *cur;
+ int nbfe = 0, nbbe = 0;
+
+ for (cur = proxy; cur; cur = cur->next) {
+ if (cur->options2 & (PR_O2_SPLIC_ANY)) {
+ if (cur->cap & PR_CAP_FE)
+ nbfe += cur->maxconn;
+ if (cur->cap & PR_CAP_BE)
+ nbbe += cur->fullconn;
+ }
+ }
+ global.maxpipes = MAX(nbfe, nbbe);
+ if (global.maxpipes > global.maxconn)
+ global.maxpipes = global.maxconn;
+ }
+
+
global.maxsock += global.maxconn * 2; /* each connection needs two sockets */
global.maxsock += global.maxpipes * 2; /* each pipe needs two FDs */