|
このページは大阪弁化フィルタによって翻訳生成されたんですわ。 |
Version?: 1.0.fr.1.0
2007-05-04
| Historique des versions | ||
|---|---|---|
| Version 1.0.fr.1.0 | 2008-05-02 | LG, ED, JPG |
| Premi?re adaptation fran?aise. | ||
| Version 1.0 | 2007-05-04 | FB |
| Premi?re ?dition, r?vis?e par TM. | ||
R?sum?
Ce document d?crit l'impl?mentation du TCP keepalive dans le noyau linux, pr?sente le concept global et d?taille ? la fois la configuration syst?me et le d?veloppement d'application.
Table des mati?res
Comprendre TCP keepalive n'est pas indispensable dans la plupart des cas, mais cela peut ?tre tr?s utile dans certaines circonstances. Il vous faudra poss?der quelques notions de base des r?seaux TCP/IP et de la programmation en langage C pour comprendre toutes les sections de ce document.
Le principal objectif de ce tutoriel (HOWTO) est de d?crire en d?tail le TCP keepalive et de pr?senter diff?rents cas d'application. Apr?s avoir d?but? avec un peu de th?orie, le propos se concentre sur l'impl?mentation des routines TCP keepalive dans les noyaux Linux actuels (2.4.x, 2.6.x), et sur les moyens dont les administrateurs syst?me peuvent tirer parti de ces routines, avec des exemples de configuration pr?cis et des astuces.
La seconde partie de ce tutoriel met en jeu l'interface de programmation
propos?e par le noyau Linux, et le mode d'?criture des applications qui
impl?mentent le TCP keepalive en langage C. Des exemples pratiques sont
pr?sent?s, et une approche du projet libkeepalive est
amorc?e, permettant aux applications de b?n?ficier par h?ritage du keepalive
sans modification de code.
Les droits de ce document, TCP Keepalive HOWTO, sont d?pos?s sous copyright (c) 2007 par Fabio Busatto. Il est permis de copier, distribuer et/ou modifier ce document dans le cadre de la Licence de Documentation Libre GNU, Version 1.1 ou ult?rieure publi?e par la Free Software Foundation; aucune section invariable, pas de texte de couverture. Un exemplaire de la licence est disponible ? l'adresse http://www.gnu.org/licenses/licenses.fr.html#GPL.
Le code source inclus dans ce document rel?ve de la licence publique g?n?rale (GPL) GNU General Public License, Version 2 ou ult?rieure publi?e par la Free Software Foundation. Un exemplaire de la licence est disponible ? l'adresse http://www.gnu.org/licenses/licenses.fr.html#GPL.
Linux est une marque d?pos?e de Linus Torvalds.
Aucune responsabilit? relative au contenu du pr?sent document ne sera endoss?e. L'utilisation des concepts, exemples et informations est ? vos propres risques. Des erreurs ou impr?cisions peuvent endommager votre syst?me. Agissez avec pr?caution, et m?me si cela est peu commun, l'auteur n'endosse aucune responsabilit? (NdT : le traducteur non plus).
Tous les droits sont d?tenus par leurs propri?taires respectifs, sauf mention particuli?re. L'utilisation de termes de ce document ne doit pas ?tre consid?r?e comme une atteinte ? la validit? d'une marque d?pos?e ou marque de service. Citer un produit ou une marque ne devrait pas ?tre consid?r? comme r?pr?hensible.
Ce travail ne doit ? personne que je devrais remercier. Mais il doit ? ma vie, et ? mon savoir aussi: donc, merci ? chacun m'ayant soutenu, avant ma naissance, actuellement, ou dans le futur. Sinc?rement.
Un merci tout sp?cial ? Tabatha, la femme patiente qui a lu mon travail et fait les corrections n?cessaires.
Vos retours sur ce document seront les bienvenus. Adressez vos ajouts,
commentaires et remarques ? l'auteur ? l'adresse mail suivante :
<fabio.busatto@sikurezza.org>.
Si vous ?tes int?ress? par la traduction de ce HOWTO en d'autres langues, n'h?sitez pas ? me contacter. Votre contribution sera la bienvenue.
Langues disponibles :
Afin de comprendre ce que fait TCP keepalive (que nous appellerons 'keepalive'), vous n'avez besoin que d'en lire le nom : keep TCP alive (maintenir TCP en vie), c'est ? dire conserver la connexion TCP. Cela signifie que vous serez en mesure de v?rifier l'?tat de votre socket de connexion (appel?e aussi socket TCP), et de d?terminer si la connexion est toujours ?tablie ou si elle est rompue.
Le concept du keepalive est tr?s simple: lorsque vous initiez une connexion TCP, vous y associez un jeu de chronom?tres. Certains de ces chronom?tres ont trait ? la proc?dure du keepalive. Quand la dur?e maximale du keepalive est atteinte, vous adressez ? l'h?te distant un paquet sonde de keepalive ne contenant aucune donn?e, avec le bit ACK positionn?. Cela est possible gr?ce aux particularit?s de TCP/IP, une sorte de ACK doubl?, et l'h?te distant n'aura aucun argument, puisque TCP est un protocole orient? flux. En retour vous aurez une r?ponse de l'h?te distant (qui n'a nul besoin d'impl?menter le keepalive, mais seulement TCP/IP), sans donn?e, et le ACK positionn?.
Si vous recevez une r?ponse ? votre sonde keepalive, vous pouvez ?tre certain que la connexion est toujours ?tablie et active sans inqui?tude pour le niveau applicatif. Concr?tement, TCP permet de maintenir un flux, sans paquet, donc un paquet de longueur z?ro n'est pas dangereux pour le programme utilisateur.
Cette m?thode est utile car si les autres points distants perdent leurs connexions (en raison d'un red?marrage par exemple) vous d?tecterez que la connexion est rompue, m?me sans avoir de flux de donn?e. Si les sondes keepalive n'obtiennent pas de r?ponse, vous pouvez certifier que la connexion ne peut plus ?tre consid?r?e comme valide et agir en cons?quence.
Vous pouvez vivre plut?t heureux sans keepalive, donc si vous lisez ces lignes, soit vous essayez de comprendre si keepalive est une r?ponse possible ? vos probl?mes, soit vous n'avez rien de plus int?ressant ? faire et c'est bien aussi. :)
Keepalive est non invasif, et dans la plupart des cas, si vous avez un doute, vous pouvez l'activer sans risque d'erreur. mais souvenez vous que c'est g?n?rateur de flux suppl?mentaire, ce qui peut avoir un impact sur les routeurs et les pare-feu.
En r?sum?, utilisez vos m?ninges et soyez prudent.
Dans la section suivante nous distinguerons les deux objectifs de keepalive:
S'assurer qu'un h?te distant n'est pas injoignable
?viter une d?connexion due ? une inactivit? r?seau.
Keepalive peut ?tre utilis? pour ?tre averti que l'h?te distant est mort avant qu'il soit capable de vous le notifier. Cela pourrait se produire en diff?rentes circonstances, une panique noyau ou une interruption soudaine du processus maintenant la connexion par exemple. Un autre cas justifiant keepalive pour d?tecter que l'h?te distant n'est pas joignable est la d?faillance du r?seau. Dans ce cas, si le r?seau n'est pas ? nouveau op?rationnel, vous ?tes dans la m?me situation que pour la mort de l'h?te distant. C'est dans ces cas de figure que les m?canismes TCP classiques ne permettent pas de s'assurer de l'?tat d'une connexion.
Songez ? une simple connexion TCP entre l'h?te A et l'h?te B: il y a la poign?e de main initiale en trois phases, le paquet SYN de A vers B, le SYN/ACK en retour de B vers A, et le ACK final de A vers B. A ce stade, nous sommes dans une situation stable : la connexion est ?tablie, et les donn?es peuvent donc ?tre envoy?es sur ce lien. Mais le probl?me survient : d?branchez l'alimentation de B et instantan?ment il s'?teint, sans rien envoyer sur le r?seau pour notifier A que la connexion va ?tre interrompue. A, de son c?t?, est pr?t ? envoyer des donn?es, et n'imagine pas que B est muet. Maintenant rebranchez l'alimentation de B et attendez que le syst?me red?marre. A et B sont de retour, mais A pr?sente une connexion toujours active vers B, alors que B l'ignore. La situation se r?sout d'elle-m?me lorsque A tente d'envoyer des donn?es ? B sur une connexion morte, et que B r?pond par un paquet RST, for?ant A ? finalement mettre fin ? la connexion.
Keepalive peut vous notifier quand un destinataire devient injoignable sans risque de faux positif. En fait, si le probl?me tient au r?seau entre les deux h?tes, le r?le du keepalive est d'attendre un temps pour tenter ? nouveau, adressant le paquet keepalive avant de notifier de la rupture du lien.
_____ _____ | | | | | A | | B | |_____| |_____| ^ ^ |--->--->--->-------------- SYN -------------->--->--->---| |---<---<---<------------ SYN/ACK ------------<---<---<---| |--->--->--->-------------- ACK -------------->--->--->---| | | | le syst?me meurt ---> X | | le syst?me red?marre ---> ^ | | |--->--->--->-------------- PSH -------------->--->--->---| |---<---<---<-------------- RST --------------<---<---<---| | |
L'autre objectif utile de keepalive est d'?viter que l'inactivit? ne provoque une d?connexion. C'est un cas fr?quent d'?tre d?connect? sans raison lorsque vous vous trouvez derri?re un proxy NAT ou un pare-feu. Ce comportement est d? aux proc?dures de surveillance des connexions des proxies et pare-feu, qui tiennent un inventaire des connexions qui les traverse. En raison des limites physiques de leurs ressources, ces machines ne peuvent conserver en m?moire qu'un nombre d?termin? de connexions. La r?gle la plus courante et la plus logique est de maintenir les connexions les plus r?centes et de mettre d'abord fin aux connexions les plus anciennes ou inactives.
Pour revenir ? nos h?tes A et B, reconnectons les. Une fois le lien ?tabli, attendons qu'un ?v?nement se produise pour le transmettre ? l'h?te distant. Qu'en est-il si cet ?v?nement se produit apr?s un long moment ? Notre connexion a sa propre dur?e, qui est inconnue du proxy. Lorsque nous finissons par transmettre des donn?es, le proxy n'est plus capable de les traiter correctement, et la connexion est rompue.
Puisque le fonctionnement normal est de mettre en t?te de liste la connexion par laquelle transitent des paquets, et de choisir la derni?re connexion de la file quand il faut en supprimer une, le fait d'envoyer p?riodiquement des paquets sur le r?seau est un bon moyen pour toujours rester en phase avec un risque minime de suppression.
_____ _____ _____ | | | | | | | A | | NAT | | B | |_____| |_____| |_____| ^ ^ ^ |--->--->--->---|----------- SYN ------------->--->--->---| |---<---<---<---|--------- SYN/ACK -----------<---<---<---| |--->--->--->---|----------- ACK ------------->--->--->---| | | | | | <--- connexion supprim?e de la table | | | | |--->- PSH ->---| <--- connexion invalide | | | |
Linux int?gre nativement le keepalive. Vous devez activer le r?seau TCP/IP
pour pouvoir l'utiliser. Vous avez aussi besoin du support de
procfs et de sysctl pour pouvoir
configurer les param?tre noyau au lancement.
Les fonctions impliquant keepalive utilisent trois variables manipul?es par l'utilisateur :
tcp_keepalive_time
intervalle entre le dernier envoi de paquet (le simple ACK n'?tant pas consid?r? comme de la donn?e) et la premi?re sonde keepalive; apr?s que la connexion ait ?t? marqu?e comme requ?rant un keepalive, ce compteur n'est plus utilis?.
tcp_keepalive_intvl
intervalle entre deux sondes keepalive, ind?pendamment de ce qui est ?chang? sur la connexion dans l'intervalle
tcp_keepalive_probes
nombre de sondes non acquitt?es ? envoyer avant de consid?rer la connexion perdue et de notifier la couche applicative.
Rappelez-vous que le support du keepalive, m?me s'il est configur? dans le
noyau, n'est pas le comportement par d?faut de Linux. Les programmes
doivent requ?rir le contr?le du keepalive pour que ses sockets puissent
utiliser l'interface setsockopt. Relativement peu de
programmes impl?mentent keepalive, mais vous pouvez facilement ajouter le
support du keepalive pour la plupart d'entre eux en suivant les
instructions d?taill?es plus avant dans ce document.
Il existe deux moyens de configurer les param?tres keepalive du noyau au travers de commandes utilisateur:
l'interface procfs
l'interface sysctl
Nous aborderons essentiellement comment proc?der au travers de l'interface
procfs car elle est la plus utilis?e, recommand?e et la plus simple ?
appr?hender. L'interface sysctl, particuli?rement sous l'aspect de l'appel
syst?me (syscall)
sysctl(2) et non de l'outil
sysctl(8),
n'est l? qu'? titre informatif.
Cette interface n?cessite quesysctl et
procfs soient inclus au noayu, et que procfs
soit mont? quelque part dans le syst?me de fichiers
(habituellement /proc, comme dans l'exemple
ci-dessous). Vous pouvez lire les valeurs des param?tres actuels
en listant avec la commande ??cat?? les fichiers du
r?pertoire /proc/sys/net/ipv4/ :
#cat /proc/sys/net/ipv4/tcp_keepalive_time7200#cat /proc/sys/net/ipv4/tcp_keepalive_intvl75#cat /proc/sys/net/ipv4/tcp_keepalive_probes9
Les deux premiers param?tres sont exprim?s en secondes, et le dernier est un nombre simple. Cela signifie que les routines keepalive attendent deux heures (7200 secs) avant d'adresser la premi?re sonde keepalive, et en adressent une nouvelle toutes les 75 secondes. Si aucune r?ponse ACK n'est re?ue apr?s neuf tentatives cons?cutives, la connexion est consid?r?e comme rompue.
La modification de ces valeurs est directe : il faut ?crire de nouvelles valeurs dans les fichiers. Supposons que souhaitiez configurer la machine pour que le keepalive d?bute apr?s dix minutes d'inactivit? sur le lien, et que des sondes soient envoy?es chaque minute. En raison de l'instabilit? de ce brin de votre r?seau et de la faible valeur de l'intervalle, supposons que vous vouliez augmenter le nombre de tentatives ? 20.
Voici comment param?trer ces valeurs :
#echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time#echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl#echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes
Pour confirmer la prise en compte des nouvelles valeurs, affichez ? nouveau le contenu des fichiers pour v?rifier qu'ils pr?sentent bien les valeurs souhait?es.
Il faut garder pr?sent ? l'esprit que procfs manipule
des fichiers sp?ciaux, et vous ne pouvez pas tout faire sur ces fichiers
qui ne sont qu'une interface vers l'environnement du noyau, non de
v?ritables fichiers. Testez vos scripts avant de les utiliser et faites
en sorte d'utiliser des modes d'acc?s simples comme dans les exemples
ci-dessus.
Vous pouvez acc?der ? l'interface gr?ce ? l'outil sysctl(8), en pr?cisant ce que vos voulez lire ou ?crire.
#sysctl \>net.ipv4.tcp_keepalive_time \>net.ipv4.tcp_keepalive_intvl \>net.ipv4.tcp_keepalive_probesnet.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_keepalive_probes = 9
Remarquez que les noms sysctl sont proches des chemins
procfs. L'?criture se fait gr?ce ? l'option -w
de sysctl
(8):
#sysctl -w \>net.ipv4.tcp_keepalive_time=600 \>net.ipv4.tcp_keepalive_intvl=60 \>net.ipv4.tcp_keepalive_probes=20net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 60 net.ipv4.tcp_keepalive_probes = 20
Remarquez que sysctl
(8) n'utilise pas
l'appel syst?me (syscall)sysctl(2), mais lit et ?crit directement
dans l'arborescence procfs, donc procfs
devra ?tre activ? dans le noyau et mont? dans le syst?me de fichiers,
comme si vous acc?diez directement aux fichiers via l'interface
procfs.
Sysctl(8) n'est qu'un moyen diff?rent de faire la m?me chose.
Il existe un autre moyen d'acc?der aux variables du noyau : l'appel
syst?me sysctl
(2). Cela peut ?tre
utile lorque procfs n'est pas disponible du fait que
la communication avec le noyau est r?alis?e directement via syscall et pas
au travers de l'arborescence procfs . Il n'existe
actuellement aucun programme qui impl?mente l'appel syscall
(souvenez-vous que
sysctl(8)
ne l'utilise pas).
Pour une utilisation d?taill? de
sysctl(2)
reportez vous au manuel (man).
Il existe diff?rents moyens de param?trer le syst?me ? chaque d?marrage.
Tout d'abord, souvenez vous que chaque distribution Linux poss?de son
propre jeu de scripts d'initialisation appel? par
init
(8).
Les configurations les plus courantes incluent soit le r?pertoire
/etc/rc.d/ , soit /etc/init.d/ .
Dans ce cas vous pouvez positionner les param?tres dans un script de
d?marrage quelconque, keepalive relisant les valeurs ? chaque fois
que ses routines en ont besoin. Donc si vous changez la valeur de
tcp_keepalive_intvl alors que la connexion est
encore active, le noyau utilisera la nouvelle valeur pour continuer.
Les commandes d'initialisation peuvent logiquement ?tre plac?es en trois
endroits diff?rents : le premier est dans la configuration r?seau,
le second dans le script rc.local , habituellement
inclus dans toutes les distributions, et connu comme ?tant le point de
configuration utilisateur au d?marrage. Le troisi?me point existe
peut-?tre d?j? sur votre syst?me. En revenant ? l'outil
sysctl
(8) , vous pouvez
voir que l'option -p charge les param?tres du fichier
de configuration /etc/sysctl.conf . Il est fr?quent
que votre script d'initialisation ex?cute d?j? sysctl -p
(un ??grep?? sur le r?pertoire de configuration le confirmera),
et vous n'avez alors qu'? ajouter les lignes dans
/etc/sysctl.conf pour qu'elles soient prises en compte
? chaque d?marrage. Pour davantage d'informations sur la syntaxe de
sysctl.conf
(5),
reportez vous au manuel.
Cette section aborde le code n?cessaire ? l'?criture d'une application utilisant keepalive. Ce n'est pas un manuel de programmation, et il requiert d'avoir une connaissance du langage C et des concepts r?seau. Je consid?re que la notion de socket vous est famili?re, de m?me que tous les aspects g?n?raux de votre application.
Les applications r?seau ne requi?rent pas toutes l'aide du keepalive. Souvenez vous qu'il s'agit de TCP keepalive. Comme vous pouvez le deviner, seules les sockets TCP peuvent en tirer parti.
La plus belle chose que vous puissiez faire en ?crivant une application est de la rendre aussi param?trable que possible, et de ne pas en forcer les choix. Si vous voulez prendre en compte le bonheur de vos utilisateurs, vous devriez impl?menter keepalive et laisser les utilisateurs d?cider s'ils veulent ou non l'utiliser en pr?voyant un param?tre de configuration ou une option de ligne de commande.
Tout ce dont vous avez besoin pour que keepalive soit activ? sur une socket particuli?re est de positionner l'option sur cette socket. Le prototype de fonction est le suivant:
int setsockopt(int s, int level, int optname,
const void *optval, socklen_t optlen)
Le premier param?tre est la socket, pr?alablement cr??e avec
socket(2); le second doit ?tre
SOL_SOCKET, et le troisi?me SO_KEEPALIVE
. Le quatri?me doit ?tre un entier boole?en, indiquant que
l'option est active, alors que le dernier est la taille de la valeur
pass?e pr?c?demment.
Conform?ment au manuel, le code retour 0
indique le succ?s, -1 est la valeur
d'erreur (et errno est correctement renseign?e).
Il existe aussi trois autres options de socket qu'il est possible de
renseigner en ?crivant votre application. Toutes utilisent le niveau
SOL_TCP au lieu de SOL_SOCKET,
et elles prennent le pas sur les variables syst?me pour la socket
courante. Si vous lisez avant d'?crire, les param?tres syst?me seront
retourn?s.
TCP_KEEPCNT : prend le pas sur
tcp_keepalive_probes
TCP_KEEPIDLE : prend le pas sur
tcp_keepalive_time
TCP_KEEPINTVL : prend le pas sur
tcp_keepalive_intvl
Voici un petit exemple qui cr?e une socket, montre que keepalive est d?sactiv?, puis l'active et v?rifie que l'option est r?ellement positionn?e.
/* --- d?but du programme de test KEEPALIVE --- */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(void);
int main()
{
int s;
int optval;
socklen_t optlen = sizeof(optval);
/* Creation de la socket */
if((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket()");
exit(EXIT_FAILURE);
}
/* Verifie l'etat de l'option keepalive */
if(getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
perror("getsockopt()");
close(s);
exit(EXIT_FAILURE);
}
printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
/* Rend l'option active */
optval = 1;
optlen = sizeof(optval);
if(setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
perror("setsockopt()");
close(s);
exit(EXIT_FAILURE);
}
printf("SO_KEEPALIVE set on socket\n");
/* Verifie a nouveau son etat */
if(getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
perror("getsockopt()");
close(s);
exit(EXIT_FAILURE);
}
printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
close(s);
exit(EXIT_SUCCESS);
}
/* --- fin du programme de test KEEPALIVE --- */
Tout le monde n'est pas d?veloppeur d'application, et tout le monde ne r??crira pas enti?rement une application pour combler le manque d'une fonctionnalit?. Peut-?tre souhaitez vous ajouter keepalive ? une application existante, et m?me si son auteur n'a pas consid?r? cela important, vous pensez que ce sera utile.
Tout d'abord, souvenez vous de ce qui a ?t? dit pr?c?demment ? propos des cas o? keepalive est n?cessaire. Ensuite vous devrez affecter les sockets TCP orient?es connexion.
Comme Linux ne fournit pas la possibilit? d'activer le support keepalive
via le noyau (les OS de type BSD le permettent souvent), le seul moyen
est d'appeler setsockopt
(2)
apr?s la cr?ation de la socket. Il y a deux solutions:
modification du code source du programme original
injection setsockopt
(2) en utilisant
la technique de pr?chargement de biblioth?que
Souvenez-vous que keepalive n'est pas orient? programme, mais orient? socket, donc si vous avez de multiples sockets, vous pouvez g?rer keepalive s?par?ment pour chacune d'entre elles. La premi?re ?tape consiste ? comprendre ce que fait le programme, la seconde ? rechercher le code pour chaque socket dans le programme. Cela peut ?tre fait en utilisant grep(1), comme suit:
#grep 'socket *(' *.c
Cela vous montrera ? peu pr?s toutes les sockets du code. L'?tape
suivante consiste ? choisir les bonnes : vous ciblez les sockets TCP,
donc recherchez PF_INET (ou AF_INET),
SOCK_STREAM et IPPROTO_TCP (ou
plus commun?ment, 0) dans les param?tres de votre
liste de sockets, et enlevez celles qui ne correspondent pas.
Il existe un autre moyen de cr?er une socket au travers de
accept(2). En ce ce cas, suivez les sockets
TCP identifi?es et v?rifiez si certaines sont en ?coute : si c'est
le cas, gardez ? l'esprit que
accept(2) retourne un descripteur de socket, qui doit ?tre ajout?
? votre liste de sockets.
Une fois les sockets identifi?es, vous pouvez proc?der aux modifications.
Le patch le plus 'fast & furious' peut consister ? simplement ajouter
la fonction setsockopt(2
) juste apr?s le bloc de cr?ation de la socket.
?ventuellement, vous pouvez ajouter des appels suppl?mentaires pour
modifier les param?tres syst?mes par d?faut de keepalive. Surtout soyez
attentif au positionnement des v?rifications d'erreurs et des handlers
de la fonction, peut-?tre en recopiant le style du code alentour. Songez
? affecter ? optval une valeur non nulle et ?
initialiser optlen avant d'appeler la fonction.
Si vous en avez le temps ou pensez que ce serait plus ?l?gant, essayez d'impl?menter compl?tement le keepalive ? votre programme, en incluant une option de ligne de commande ou un param?tre de configuration pour laisser ? l'utilisateur la libert? d'utiliser ou non keepalive.
Dans de nombreux cas vous n'avez pas la possibilit? de modifier le code source d'une application, ou bien lorsque vous devez activer keepalive pour tous vos programmes, tout patcher et tout recompiler n'est pas recommand?.
Le projet libkeepalive a vu le jour pour faciliter l'impl?mentation du keepalive au sein des applications puisque le noyau Linux ne permet pas de le faire nativement (comme le fait BSD). La page d'accueil du projet libkeepalive est disponible ? l'adresse http://libkeepalive.sourceforge.net/
Il consiste en une biblioth?que partag?e qui outrepasse l'appel syst?me
socket de la plupart des ex?cutables, sans aucun besoin de les recompiler
ni de les modifier. La technique repose sur la fonctionnalit? de
pr?-chargement (preloading) de
ld.so(8), chargeur inclus dans Linux, qui
qui permet le chargement de biblioth?ques partag?es avec une priorit?
sup?rieure ? la normale. Les programmes utilisent habituellement l'appel
de fonction socket
(2) situ? dans la
glibc, librairie partag?e; avec libkeepalive
il est possible d'encapsuler la fonction
setsockopt(2) juste apr?s la cr?ation, retournant
au programme principal une socket avec keepalive d?j? positionn?.
En raison des m?canismes utilis?s pour r?aliser l'appel syst?me,
ce proc?d? ne fonctionne pas lorsque la fonction socket est compil?e
statiquement dans le binaire, comme dans le cas d'un programme li? par
l'option -static de
gcc(1
).
Apr?s avoir t?l?charg? et install? libkeepalive,
vous serez en mesure d'ajouter le support de keepalive ? vos programmes
sans ?tre root au pr?alable, simplement en
initialisant la variable d'environnement LD_PRELOAD
avant d'ex?cuter le programme. Au fait, le super utilisateur peut aussi
forcer la pr?-chargement au travers d'une configuration globale, et
les utilisateurs peuvent choisir de le d?sactiver en positionnant
la variable d'environnement KEEPALIVE ? off.
L'environnement est aussi utilis? pour positionner des valeurs
sp?cifiques pour les param?tres de keepalive, vous avez donc la
possibilit? de g?rer chaque programme de fa?on distincte,
en initialisant KEEPCNT, KEEPIDLE
et KEEPINTVL avant de lancer l'application.
Voici un exemple d'utilisation de libkeepalive :
$testSO_KEEPALIVE is OFF$LD_PRELOAD=libkeepalive.so \>KEEPCNT=20 \>KEEPIDLE=180 \>KEEPINTVL=60 \>testSO_KEEPALIVE is ON TCP_KEEPCNT = 20 TCP_KEEPIDLE = 180 TCP_KEEPINTVL = 60
Et vous pouvez utiliser strace (1) pour comprendre ce qui se passe:
$strace testexecve("test", ["test"], [/* 26 vars */]) = 0 [..] open("/lib/libc.so.6", O_RDONLY) = 3 [..] socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 getsockopt(3, SOL_SOCKET, SO_KEEPALIVE, [0], [4]) = 0 close(3) = 0 [..] _exit(0) = ?$LD_PRELOAD=libkeepalive.so \>strace testexecve("test", ["test"], [/* 27 vars */]) = 0 [..] open("/usr/local/lib/libkeepalive.so", O_RDONLY) = 3 [..] open("/lib/libc.so.6", O_RDONLY) = 3 [..] open("/lib/libdl.so.2", O_RDONLY) = 3 [..] socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3 setsockopt(3, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0 setsockopt(3, SOL_TCP, TCP_KEEPCNT, [20], 4) = 0 setsockopt(3, SOL_TCP, TCP_KEEPIDLE, [180], 4) = 0 setsockopt(3, SOL_TCP, TCP_KEEPINTVL, [60], 4) = 0 [..] getsockopt(3, SOL_SOCKET, SO_KEEPALIVE, [1], [4]) = 0 [..] getsockopt(3, SOL_TCP, TCP_KEEPCNT, [20], [4]) = 0 [..] getsockopt(3, SOL_TCP, TCP_KEEPIDLE, [180], [4]) = 0 [..] getsockopt(3, SOL_TCP, TCP_KEEPINTVL, [60], [4]) = 0 [..] close(3) = 0 [..] _exit(0) = ?
Pour d'autres informations, visitez la page d'accueil du projet libkeepalive : http://libkeepalive.sourceforge.net/