MEDIUM: backend: add the 'first' balancing algorithm

The principle behind this load balancing algorithm was first imagined
and modeled by Steen Larsen then iteratively refined through several
work sessions until it would totally address its original goal.

The purpose of this algorithm is to always use the smallest number of
servers so that extra servers can be powered off during non-intensive
hours. Additional tools may be used to do that work, possibly by
locally monitoring the servers' activity.

The first server with available connection slots receives the connection.
The servers are choosen from the lowest numeric identifier to the highest
(see server parameter "id"), which defaults to the server's position in
the farm. Once a server reaches its maxconn value, the next server is used.
It does not make sense to use this algorithm without setting maxconn. Note
that it can however make sense to use minconn so that servers are not used
at full load before starting new servers, and so that introduction of new
servers requires a progressively increasing load (the number of servers
would more or less follow the square root of the load until maxconn is
reached). This algorithm ignores the server weight, and is more beneficial
to long sessions such as RDP or IMAP than HTTP, though it can be useful
there too.
diff --git a/include/types/backend.h b/include/types/backend.h
index c75f2b2..8672bd2 100644
--- a/include/types/backend.h
+++ b/include/types/backend.h
@@ -24,6 +24,7 @@
 
 #include <common/config.h>
 #include <types/lb_chash.h>
+#include <types/lb_fas.h>
 #include <types/lb_fwlc.h>
 #include <types/lb_fwrr.h>
 #include <types/lb_map.h>
@@ -52,6 +53,7 @@
 
 /* BE_LB_CB_* is used with BE_LB_KIND_CB */
 #define BE_LB_CB_LC     0x00000  /* least-connections */
+#define BE_LB_CB_FAS    0x00001  /* first available server (opposite of leastconn) */
 
 #define BE_LB_PARM      0x000FF  /* mask to get/clear the LB param */
 
@@ -76,6 +78,7 @@
 #define BE_LB_ALGO_NONE (BE_LB_KIND_NONE | BE_LB_NEED_NONE)    /* not defined */
 #define BE_LB_ALGO_RR   (BE_LB_KIND_RR | BE_LB_NEED_NONE)      /* round robin */
 #define BE_LB_ALGO_LC   (BE_LB_KIND_CB | BE_LB_NEED_NONE | BE_LB_CB_LC)    /* least connections */
+#define BE_LB_ALGO_FAS  (BE_LB_KIND_CB | BE_LB_NEED_NONE | BE_LB_CB_FAS)   /* first available server */
 #define BE_LB_ALGO_SRR  (BE_LB_KIND_RR | BE_LB_NEED_NONE | BE_LB_RR_STATIC) /* static round robin */
 #define BE_LB_ALGO_SH	(BE_LB_KIND_HI | BE_LB_NEED_ADDR | BE_LB_HASH_SRC) /* hash: source IP */
 #define BE_LB_ALGO_UH	(BE_LB_KIND_HI | BE_LB_NEED_HTTP | BE_LB_HASH_URI) /* hash: HTTP URI  */
@@ -93,6 +96,7 @@
 #define BE_LB_LKUP_RRTREE 0x20000  /* FWRR tree lookup */
 #define BE_LB_LKUP_LCTREE 0x30000  /* FWLC tree lookup */
 #define BE_LB_LKUP_CHTREE 0x40000  /* consistent hash  */
+#define BE_LB_LKUP_FSTREE 0x50000  /* FAS tree lookup */
 #define BE_LB_LKUP        0x70000  /* mask to get just the LKUP value */
 
 /* additional properties */
@@ -129,6 +133,7 @@
 	struct lb_fwrr fwrr;
 	struct lb_fwlc fwlc;
 	struct lb_chash chash;
+	struct lb_fas fas;
 	/* Call backs for some actions. Some may be NULL (thus should be ignored). */
 	void (*update_server_eweight)(struct server *);  /* to be called after eweight change */
 	void (*set_server_status_up)(struct server *);   /* to be called after status changes to UP */
diff --git a/include/types/lb_fas.h b/include/types/lb_fas.h
new file mode 100644
index 0000000..4590a96
--- /dev/null
+++ b/include/types/lb_fas.h
@@ -0,0 +1,40 @@
+/*
+ * include/types/lb_fash
+ * Types for First Available Server load balancing algorithm.
+ *
+ * Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, version 2.1
+ * exclusively.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _TYPES_LB_FAS_H
+#define _TYPES_LB_FAS_H
+
+#include <common/config.h>
+#include <ebtree.h>
+
+struct lb_fas {
+	struct eb_root act;	/* weighted least conns on the active servers */
+	struct eb_root bck;	/* weighted least conns on the backup servers */
+};
+
+#endif /* _TYPES_LB_FAS_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/include/types/server.h b/include/types/server.h
index ee83c1e..c0729fc 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -2,7 +2,7 @@
  * include/types/server.h
  * This file defines everything related to servers.
  *
- * Copyright (C) 2000-2011 Willy Tarreau - w@1wt.eu
+ * Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -155,7 +155,7 @@
 	short check_status, check_code;		/* check result, check code */
 	char check_desc[HCHK_DESC_LEN];		/* health check descritpion */
 
-	int puid;				/* proxy-unique server ID, used for SNMP */
+	int puid;				/* proxy-unique server ID, used for SNMP, and "first" LB algo */
 
 	char *check_data;			/* storage of partial check results */
 	int check_data_len;			/* length of partial check results stored in check_data */