* released 1.1.0
* added OpenBSD, Linux-2.2 and Linux-2.4 targets to the Makefile
* added a Formilux init script
* fixed a few timeout bugs
* rearranged the task scheduler subsystem to improve performance,
  add new tasks, and make it easier to later port to librt ;
* allow multiple accept() for one select() wake up ;
* implemented internal load balancing with basic health-check ;
* cookie insertion and header add/replace/delete, with better strings
  support.
* reworked buffer handling to fix a few rewrite bugs, and
  improve overall performance.
* implement the "purge" option to delete server cookies in direct mode.
* fixed some error cases where the maxfd was not decreased.
* now supports transparent proxying, at least on linux 2.4.
* soft stop works again (fixed select timeout computation).
* it seems that TCP proxies sometimes cannot timeout.
* added a "quiet" mode.
* enforce file descriptor limitation on socket() and accept().
diff --git a/doc/haproxy.txt b/doc/haproxy.txt
index 36bd2ea..4f5ec14 100644
--- a/doc/haproxy.txt
+++ b/doc/haproxy.txt
@@ -1,9 +1,9 @@
 
          		     H A - P r o x y
          		     ---------------
-         		      version 1.0.0
+         		      version 1.1.0
 			      willy tarreau
-			       2001/12/16
+			       2002/03/10
 
 ==============
 |Introduction|
@@ -12,8 +12,11 @@
 HA-Proxy est un relais TCP/HTTP offrant des facilités d'intégration en
 environnement hautement disponible. En effet, il est capable de :
   - assurer un aiguillage statique défini par des cookies ;
+  - assurer une répartition de charge avec création de cookies pour
+    assurer la persistence de session ;
   - fournir une visibilité externe de son état de santé ;
   - s'arrêter en douceur sans perte brutale de service.
+  - modifier/ajouter/supprimer des entêtes dans la requête et la réponse.
 
 Il requiert peu de ressources, et son architecture événementielle
 mono-processus lui permet facilement de gérer plusieurs milliers de
@@ -51,7 +54,7 @@
 
 L'analyseur du fichier de configuration ignore des lignes vides, les
 espaces, les tabulations, et tout ce qui est compris entre le symbole
-'#' et la fin de la ligne.
+'#' (s'il n'est pas précédé d'un '\'), et la fin de la ligne.
 
 
 Serveur
@@ -102,7 +105,7 @@
 Mode TCP
 --------
 Dans ce mode, le service relaye, dès leur établissement, les
-connexions TCP vers un unique serveur distant. Aucun traitement n'est
+connexions TCP vers un ou plusieurs serveurs. Aucun traitement n'est
 effectué sur le flux. Il s'agit simplement d'une association
 <adresse_source:port_source> <adresse_destination:port_destination>.
 Pour l'utiliser, préciser le mode TCP sous la déclaration du relais :
@@ -236,6 +239,30 @@
 	mode http
 	cookie SERVERID
 
+On peut modifier l'utilisation du cookie pour la rendre plus
+intelligente vis-à-vis des applications relayées. Il est possible,notamment
+de supprimer ou réécrire un cookie retourné par un serveur accédé en direct,
+et d'insérer un cookie dans une réponse HTTP orientée vers un serveur
+sélectionné en répartition de charge.
+
+Pour ne conserver le cookie qu'en accès indirect, donc à travers le
+dispatcheur, et le supprimer lors des accès directs :
+
+	cookie SERVERID indirect
+
+Pour réécrire le nom du serveur dans un cookie lors d'un accès direct :
+
+	cookie SERVERID rewrite
+
+Pour créer un cookie comportant le nom du serveur lors d'un accès en
+répartition de charge interne. Dans ce cas, il est indispensable que tous les
+serveurs aient un cookie renseigné.
+
+	cookie SERVERID insert
+
+Remarque: Il est possible de combiner 'insert' avec 'indirect' ou 'rewrite'
+pour s'adapter à des applications générant déjà le cookie, avec un contenu
+invalide. Il suffit pour cela de les spécifier sur la même ligne.
 
 Assignation d'un serveur à une valeur de cookie
 ===============================================
@@ -243,10 +270,12 @@
 En mode HTTP, il est possible d'associer des serveurs à des valeurs de
 cookie par le paramètre "server". La syntaxe est :
 
-    server <valeur> <adresse_ip>:<port>
+    server <identifiant> <adresse_ip>:<port> cookie <valeur>
 
-<valeur> est la valeur trouvée dans le cookie,
+<identifiant> est un nom quelconque de serveur utilisé pour
+l'identifier dans la configuration (erreurs...).
 <adresse_ip>:<port> le couple adresse-port sur lequel le serveur écoute.
+<valeur> est la valeur trouvée dans le cookie,
 
 Exemple : le cookie SERVERID peut contenir server01 ou server02
 -------
@@ -254,18 +283,64 @@
 	mode http
 	cookie SERVERID
 	dispatch 192.168.1.100:80
-	server server01 192.168.1.1:80
-	server server02 192.168.1.2:80
+	server web1 192.168.1.1:80 cookie server01
+	server web2 192.168.1.2:80 cookie server02
+
+Attention : la syntaxe a changé depuis la version 1.0.
+---------
+
+Répartiteur de charge interne
+=============================
+
+Le relais peut effectuer lui-même la répartition de charge entre les
+différents serveurs décrits pour un service donné, en mode TCP comme
+en mode HTTP. Pour cela, on précise le mot clé 'balance' dans la
+définition du service, éventuellement suivi du nom d'un algorithme de
+répartition. En version 1.1.0, seul 'roundrobin' est géré, et c'est
+aussi la valeur implicite par défaut. Il est évident qu'en cas
+d'utilisation du répartiteur interne, il ne faudra pas spécifier
+d'adresse de dispatch, et qu'il faudra au moins un serveur.
+
+Exemple : même que précédemment en répartition interne
+-------
+
+    listen http_proxy 0.0.0.0:80
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	server web1 192.168.1.1:80 cookie server01
+	server web2 192.168.1.2:80 cookie server02
+
 
+Surveillance des serveurs
+=========================
 
-Reconnexion vers le répartiteur
-===============================
+A cette date, l'état des serveurs n'est testé que par établissement
+de connexion TCP toutes les 2 secondes, avec 3 essais pour déclarer
+un serveur en panne, 2 pour le déclarer utilisable. Un serveur hors
+d'usage ne sera pas utilisé dans le processus de répartition de charge
+interne. Pour activer la surveillance, ajouter le mot clé 'check' à la
+fin de la déclaration du serveur.
+
+Exemple : même que précédemment avec surveillance
+-------
+
+    listen http_proxy 0.0.0.0:80
+	mode http
+	cookie SERVERID
+	balance roundrobin
+	server web1 192.168.1.1:80 cookie server01 check
+	server web2 192.168.1.2:80 cookie server02 check
+
+
+Reconnexion vers un répartiteur en cas d'échec direct
+=====================================================
 
 En mode HTTP, si un serveur défini par un cookie ne répond plus, les
 clients seront définitivement aiguillés dessus à cause de leur cookie,
 et de ce fait, définitivement privés de service. La spécification du
-paramètre "redisp" autorise dans ce cas à renvoyer les connexions
-échouées vers l'adresse de répartition (dispatch) afin d'assigner un
+paramètre "redispatch" autorise dans ce cas à renvoyer les connexions
+échouées vers le répartiteur (externe ou interne) afin d'assigner un
 nouveau serveur à ces clients.
 
 Exemple :
@@ -274,9 +349,31 @@
 	mode http
 	cookie SERVERID
 	dispatch 192.168.1.100:80
+	server web1 192.168.1.1:80 cookie server01
+	server web2 192.168.1.2:80 cookie server02
+	redispatch # renvoyer vers dispatch si serveur HS.
+
+Fonctionnement en mode transparent
+==================================
+
+En mode HTTP, le mot clé "transparent" permet d'intercepter des
+sessions routées à travers la machine hébergeant le proxy. Dans
+ce mode, on ne précise pas l'adresse de répartition "dispatch",
+car celle-ci est tirée de l'adresse destination de la session
+détournée. Le système doit permettre de rediriger les paquets
+vers un processus local.
+
+Exemple :
+-------
+    listen http_proxy 0.0.0.0:65000
+	mode http
+	transparent
+	cookie SERVERID
 	server server01 192.168.1.1:80
 	server server02 192.168.1.2:80
-	redisp # renvoyer vers dispatch si serveur HS.
+
+    # iptables -t nat -A PREROUTING -i eth0 -p tcp -d 192.168.1.100 \
+      --dport 80 -j REDIRECT --to-ports 65000
 
 Journalisation des connexions
 =============================
@@ -307,49 +404,92 @@
     local0, local1, local2, local3, local4, local5, local6, local7
 
 
-Remplacement d'entêtes par expressions régulières
-=================================================
+Modification des entêtes HTTP
+=============================
 
 En mode HTTP uniquement, il est possible de remplacer certains entêtes
-client et/ou serveur à partir d'expressions régulières. Deux
-limitations cependant :
-  - il n'est pas encore possible de supprimer un entête ni d'en
-    ajouter un ; On peut en général s'en sortir avec des
-    modifications.
-  - les entêtes fournis au milieu de connexions persistentes
-    (keep-alive) ne sont pas vus.
+dans la requête et/ou la réponse à partir d'expressions régulières. Une
+limitation cependant : les entêtes fournis au milieu de connexions
+persistentes (keep-alive) ne sont pas vus. Les données ne sont pas
+affectées, ceci ne s'applique qu'aux entêtes.
 
 La syntaxe est :
-   cliexp <search> <replace>   pour les entêtes client
-   srvexp <search> <replace>   pour les entêtes serveur
+   reqadd <string>             pour ajouter un entête dans la requête
+   reqrep <search> <replace>   pour modifier la requête
+   reqrep <search>             pour supprimer un entête dans la requête
+
+   rspadd <string>             pour ajouter un entête dans la réponse
+   rsprep <search> <replace>   pour modifier la réponse
+   rsprep <search>             pour supprimer un entête dans la réponse
+
 
 <search> est une expression régulière compatible GNU regexp supportant
 le groupage par parenthèses (sans les '\'). Les espaces et autres
 séparateurs doivent êtres précédés d'un '\' pour ne pas être confondus
-avec la fin de la chaîne.
+avec la fin de la chaîne. De plus, certains caractères spéciaux peuvent
+être précédés d'un backslach ('\') :
+
+  \t   pour une tabulation
+  \r   pour un retour charriot
+  \n   pour un saut de ligne
+  \    pour différencier un espace d'un séparateur
+  \#   pour différencier un dièse d'un commentaire
+  \\   pour un backslash
+  \xXX pour un caractère spécifique XX (comme en C)
 
-<replace> contient la chaîne remplaçant la portion vérifiée par
-l'expression. Elle peut inclure des espaces et tabulations précédés
-par un '\', faire référence à un groupe délimité par des parenthèses
-dans l'expression régulière, par sa position numérale. Les positions
-vont de 1 à 9, et sont codées par un '\' suivi du chiffre désiré. Il
-est également possible d'insérer un caractère non imprimable (utile
-pour le saut de ligne) inscrivant '\x' suivi du code hexadécimal de ce
-caractère (comme en C).
 
-Remarque : la première ligne de la requête et celle de la réponse sont
-traitées comme des entêtes, ce qui permet de réécrire des URL et des
-codes d'erreur.
+<replace> contient la chaîne remplaçant la portion vérifiée par l'expression.
+Elle peut inclure les caractères spéciaux ci-dessus, faire référence à un
+groupe délimité par des parenthèses dans l'expression régulière, par sa
+position numérale. Les positions vont de 1 à 9, et sont codées par un '\'
+suivi du chiffre désiré. Il est également possible d'insérer un caractère non
+imprimable (utile pour le saut de ligne) inscrivant '\x' suivi du code
+hexadécimal de ce caractère (comme en C).
+
+<string> représente une chaîne qui sera ajoutée systématiquement après la
+dernière ligne d'entête.
+
+Remarques :
+---------
+  - la première ligne de la requête et celle de la réponse sont traitées comme
+    des entêtes, ce qui permet de réécrire des URL et des codes d'erreur.
+  - 'reqrep' est l'équivalent de 'cliexp' en version 1.0, et 'rsprep' celui de
+    'srvexp'. Ces noms sont toujours supportés mais déconseillés.
+  - pour des raisons de performances, le nombre total de caractères ajoutés sur
+    une requête ou une réponse est limité à 256. Cette valeur est modifiable dans
+    le code. Pour un usage temporaire, on peut gagner de la place en supprimant
+    quelques entêtes inutiles avant les ajouts.
 
 Exemples :
-----------
-	cliexp	^(GET.*)(.free.fr)(.*) \1.online.fr\3
-	cliexp	^(POST.*)(.free.fr)(.*) \1.online.fr\3
-	cliexp	^Proxy-Connection:.*	Proxy-Connection:\ close
-	srvexp	^Proxy-Connection:.*	Proxy-Connection:\ close
-	srvexp	^(Location:\ )([^:]*://[^/]*)(.*) \1\3
+--------
+	reqrep	^(GET.*)(.free.fr)(.*) \1.online.fr\3
+	reqrep	^(POST.*)(.free.fr)(.*) \1.online.fr\3
+	reqrep	^Proxy-Connection:.*	Proxy-Connection:\ close
+	rsprep	^Server:.* Server:\ Tux-2.0
+	rsprep	^(Location:\ )([^:]*://[^/]*)(.*) \1\3
+	rspdel  ^Connection:.*
+	rspadd	Connection:\ close
 
 
+Répartition avec persistence
+============================
+
+La combinaison de l'insertion de cookie avec la répartition de charge interne
+permet d'assurer une persistence dans les sessions HTTP d'une manière
+pratiquement transparente pour les applications. Le principe est simple :
+  - assigner un cookie à chaque serveur
+  - effectuer une répartition interne
+  - insérer un cookie dans les réponses issues d'une répartition
+
+Exemple :
+-------
+    listen application 0.0.0.0:80
+	mode http
+	cookie SERVERID insert indirect
+	balance roundrobin
+	server 192.168.1.1:80 cookie server01 check
+	server 192.168.1.2:80 cookie server02 check
+
 =====================
 |Paramétrage système|
 =====================
@@ -360,13 +500,15 @@
 echo 131072 > /proc/sys/fs/file-max
 echo 65536 > /proc/sys/net/ipv4/ip_conntrack_max
 echo 1024 60999 > /proc/sys/net/ipv4/ip_local_port_range
-echo 16384 > /proc/sys/net/ipv4/ip_queue_maxlen
+echo 32768 > /proc/sys/net/ipv4/ip_queue_maxlen
 echo 60 > /proc/sys/net/ipv4/tcp_fin_timeout
-echo 4096 > /proc/sys/net/ipv4/tcp_max_orphans
+echo 262144 > /proc/sys/net/ipv4/tcp_max_orphans
 echo 16384 > /proc/sys/net/ipv4/tcp_max_syn_backlog
 echo 262144 > /proc/sys/net/ipv4/tcp_max_tw_buckets
 echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
 echo 0 > /proc/sys/net/ipv4/tcp_timestamps
-ulimit -n 65536
+echo 0 > /proc/sys/net/ipv4/tcp_sack
+echo 0 > /proc/sys/net/ipv4/tcp_ecn
+ulimit -n 131072
 
 -- fin --