RFC IRC : Implémentations actuelles
La seule implémentation
actuelle de ce protocole est le serveur IRC version 2.8. Les versions
précédentes peuvent implémenter certaines ou toutes les commandes décrites dans
ce document en utilisant les messages NOTICE à la place des réponses numériques.
Malheureusement, à causes des problèmes de compatibilité ascensionnelle, les
implémentations de certaines parties de ce document diffèrent de ce qui est
spécifié. Une différence notable est : * La
présence de tout LF ou CR dans n'importe ou dans le message marque sa fin (au
lieu de la séquence préconisée CR-LF) ;
Le reste de cette section traite d'issues qui sont pour la plupart
intéressantes pour ceux qui veulent implémenter un serveur, mais certaines
s'appliquent aussi directement aux clients.
8.1 Protocole Réseau: TCP - Pourquoi il est le plus
approprié.IRC a été implémenté sur TCP car TCP fourni un protocole réseau
fiable qui est approprié à cette échelle de discussions. L'utilisation d'IP
multicast est une alternative, mais n'est pas très répandue à l'heure actuelle.
8.1.1 Support des sockets UnixEtant donné que les
domaines de sockets Unix permettent les opérations listen/connect, les
implémentations actuelles peuvent être configurées pour écouter et accepter
aussi bien les clients que les serveurs sur un domaine de socket Unix. On
reconnaît les sockets à un nom d'hôte commençant par un '/'.
Lors de la communication des informations au sujet d'un domaine de socket
Unix, le serveur doit remplacer le nom de chemin par le vrai nom d'hôte, à moins
que le nom socket soit demandé.
8.2 Traitement des commandesAfin de fournir des E/S
réseaux 'non-tamponnées' utiles aux clients et aux serveurs, à chaque connection
est associée son propre 'tampon d'entrée' dans lequel les résultats de lectures
et traitements les plus récents sont conservés. Une taille de tampon de 512
octets et utilisée afin de contenir un message complet, bien qu'il en contienne
habituellement plusieurs. Le tampon privé est traité après toute opération de
lecture à la recherche de messages valides. Lors du traitement de messages
multiples en provenance d'un client, on doit prendre soin au cas où un des
messages causerait le départ du client.
8.3 Distribution de messageIl est courant de trouver des
liens réseaux saturés ou des hôtes à qui vous envoyer des données et qui sont
incapables d'en faire autant. Bien qu'Unix gère typiquement cela à travers la
fenêtre TCP et ses tampons internes, le serveur a généralement de grandes
quantités de données à envoyer (spécialement lorsqu'une nouvelle connection
serveur/serveur est crée) et les petits tampons fournis dans le noyau ne sont
pas suffisant à la queue de sortie. Pour alléger ce problème, une "queue
d'envoi" est utilisée comme une queue FIFO pour les données à envoyer. Une
"queue d'envoi" typique peut croître jusqu'à 200ko sur un gros réseau IRC, avec
des connections réseau lentes quand un nouveau serveur se connecte.
Lorsqu'il traite ses connections, un serveur doit d'abord lire et traiter
toutes les données entrantes, en mémorisant les données qui seront émises. Quand
toutes les entrées disponibles sont traitées, la queue d'envoi est expédiée.
Cela réduit le nombre d'appels systèmes write() et aide TCP à faire des paquets
plus gros.
8.4 La vie d'une connectionPour détecter quand une
connection est morte ou ne répond plus, le serveur doit envoyer un PING à toute
les connections dont il n'a pas eu de réponse depuis un temps donné.
Si une connection ne répond pas à temps, elle est fermée en utilisant les
procédures appropriées. Une connection est également lâchée si son sendq grossi
au-delà du maximum autorisé, car il vaut mieux fermer une connection lente que
d'avoir le processus serveur bloqué.
8.5 Etablissement d'une connection serveur à clientLors
de la connection à un serveur IRC, on envoie au client le MOTD (s'il est
présent) ainsi que le nombre actuel d'utilisateur et de serveurs (comme pour la
commande LUSER). Le serveur doit également envoyer un message non équivoque au
client, qui stipule son nom, sa version, ainsi que tout autre message
d'introduction qui lui semble approprié.
Après cela, le serveur doit envoyer le pseudo du nouvel utilisateur, et toute
autre information aussi bien fournies par le client (commande USER) que celles
trouvées par le serveur (serveurs DNS et IDENT). Le serveur doit envoyer ces
informations à la première commande NICK suivi de USER.
8.6 Etablissement d'une connection serveur/serveurLe
processus d'établissement d'une connection serveur à serveur est plein de
dangers, car il y a de nombreux domaines où un problème peut survenir { - the
least of which are race conditions.}
Après avoir reçu une connection suivi d'une paire PASS/SERVER qui a été
reconnue valide, le serveur doit répondre avec ses propres informations
PASS/SERVER pour cette connection, ainsi que toutes les informations d'état
qu'il connais comme décrit ci-dessous.
Quand le serveur initiant reçoit la paire PASS/SERVER, lui aussi vérifie que
le serveur répondant est authentifié correctement avant d'accepter la connection
comme étant ce serveur.
8.6.1 Echange des informations d'état des serveurs à la
connectionL'ordre des informations d'état échangées entre les serveurs est
essentiel. L'ordre requis est le suivant :
- tous les autres serveurs connus ;
- toutes les informations utilisateurs connues ;
- toutes les informations de canaux connues.
Les informations
concernant les serveurs sont envoyées avec des messages SERVER supplémentaires,
les informations utilisateurs avec des messages NICK/USER/MODE/JOIN et celles
des canaux avec des messages MODE.
NOTE : Les sujets des canaux ne sont PAS échangés ici, car la commande TOPIC
écrase toute information de sujet précédente, si bien que, au mieux, les deux
côtés de la connection échangeraient les sujets.
En passant les informations d'état concernant les serveurs en premier, toutes
les collisions avec des serveurs qui existeraient déjà ont lieu avant les
collisions de pseudo dues à un second serveur introduisant un pseudonyme
particulier. En raison de l'obligation de réseau IRC à n'exister que sur un
graphe acyclique, il est possible que le réseau se soit déjà reconnecté
ailleurs, et l'endroit où la collision a lieu indique ou le réseau doit être
divisé.
8.7 Terminaison des connection serveur/client.Lorsqu'une
connection client se ferme, un message QUIT est généré de la part du client par
le serveur sur lequel le client était connecté. Aucun autre message ne doit être
généré ou utilisé.
8.8 Terminaison des connections serveur/serveur.Si une
connection serveur/serveur est fermée, soit par un SQUIT généré à distance, soit
par une cause 'naturelle', le reste du réseau IRC doit le prendre en compte, et
c'est au serveur qui détecte la fermeture de faire circuler l'information. Le
serveur envoie une liste de SQUIT (un par serveur au-delà de la connection
coupée) et une liste de QUIT (un par client au-delà de la connection coupée).
8.9 Suivi des changements de pseudonymesTous les
serveurs IRC doivent garder un historique des changements récents de
pseudonymes. Cela est nécessaire pour offrir au serveur la possibilité de garder
le contact quand une commande concerne un utilisateur changeant de pseudo. Les
commandes qui doivent vérifier un changement de pseudo sont :
- KILL (le pseudo se faisant tuer)
- MODE (+/- o,v)
- KICK (le pseudo se faisant exclure)
Aucune autre commande ne doit
vérifier un changement de pseudo.
Dans les cas ci-dessus, le serveur doit tout d'abord vérifier l'existence du
pseudonyme, puis vérifier l'historique pour voir à qui appartient ce pseudo.
Cela réduit les chances de problèmes, mais ne les empêche pas complètement, ce
qui peu résulter au final de l'affectation du mauvais client. Lors du traçage
des changements de pseudonymes pour une des commandes ci-dessus, il est
recommandé qu'un intervalle de temps soit donné, et que les entrées trop vielles
soient ignorées.
Pour un historique parfait, un serveur devrait être capable de garder les
pseudonymes de tous les clients qui ont décidé d'un changement. La taille est
limitée par d'autres facteurs (tels que la mémoire, ...)
8.10 Contrôle d'inondation des clientsDans un gros
réseau de serveurs IRC interconnectés, il est assez facile, pour un simple
client connecté, d'émettre un flux continu de messages qui résultent non
seulement en l'inondation du réseau, mais aussi en la dégradation de la qualité
de service fournie aux autres clients. Au lieu de demander à chaque 'victime' de
gérer sa propre protection, la protection contre les inondations est incluse
dans le serveur et est appliquée à tous les clients, à l'exception des services.
L'algorithme actuel est le suivant :
- vérifier si les 'messages de temps' des clients est inférieur au temps
courant (et le mettre à l'heure courante le temps échéant) ;
- lire toute donnée présentée par le client ;
- tant que le compteur est inférieur à dix secondes par rapport à l'heure
actuelle, traiter tout message actuel et pénaliser le client de deux secondes
par message ;
Ce qui, en essence, signifie qu'un client ne peut
envoyer plus d'un message toutes les deux secondes sans être affecté.
8.11 Boucles non bloquantesDans un environnement temps
réel, il est essentiel qu'un processus serveur attende aussi peu que possible,
de manière à ce que tous les clients soient servis justement. Evidement, cela
nécessite des ES non bloquantes sur toutes les opérations de lecture/écriture du
réseau. Pour les connections de serveur normales, ce n'est pas compliqué, mais
il y a des opérations gérées qui peuvent causer un blocage du serveur (telles
que les lectures disque). Quand c'est possible, de telles activités doivent être
exécutée avec un délai d'attente maximal court.
8.11.1 Recherche du nom d'hôte (DNS)L'utilisation
des librairies de résolution standards de Berkeley et autres entraîne de gros
délais, dans les cas où les réponses n'arrivent pas. Afin d'éviter cela, un jeu
de routines DNS indépendantes ont été écrites, où les opérations DNS ont été
écrites avec des E/S non bloquantes et testées depuis la boucle d'E/S principale
du serveur.
8.11.2 Recherche du nom d'utilisateur (IDENT)Bien
qu'il y ait de nombreuses libraires IDENT à utiliser et inclure dans d'autres
programmes, elles posent des problèmes puisqu'elles opèrent de façon synchrone,
et résultent en de nombreuses attentes. Encore une fois, la solution a été
d'écrire un jeu de routines qui coopèrent avec le reste du serveur, et utilisent
des E/S non bloquantes.
8.12 Fichier de configurationAfin de fournir une façon
flexible de configurer et de lancer le serveur, il est recommandé qu'un fichier
de configuration soit utilisé, qu'il contienne les instructions du serveur
suivantes :
- de quels hôtes accepter une connection en tant que client;
- de quels hôtes accepter une connection en tant que serveur;
- à quels hôtes se connecter (aussi bien activement que passivement) ;
- informations sur l'emplacement du serveur (université, ville/état,
entreprise par exemple) ;
- quels sont les responsables du serveur, avec une adresse email où ils
peuvent être contactés ;
- noms d'hôtes et mots de passe pour les clients qui souhaitent obtenir
l'accès restreint aux commandes d'opérateur.
Lors de la spécification
des noms d'hôtes, les noms de domaines et la notation 'point' (127.0.0.1)
doivent être tous les deux gérées. Il doit être possible de préciser un mot de
passe à utiliser/accepter pour toutes les connections entrantes et sortantes
(bien que les connections sortantes soient toutes à destination de serveurs).
La liste ci-dessus est le minimum obligatoire pour tout serveur qui souhaite
se connecter à un autre serveur. Parmi les autres éléments utiles, on trouve :
- spécification de quels serveurs un serveur peut introduire ;
- jusqu'à quelle longueur une branche de serveur peut aller ;
- heures durant lesquelles un client peut se connecter
8.12.1 Autorisation des connections de clientsUn
serveur doit utiliser une sorte de 'liste de contrôle d'accès' (soit dans le
fichier de configuration ou ailleurs) qu'il lit au démarrage et utilise pour
décider quels hôtes les clients peuvent utiliser pour se connecter.
'Accepter' et 'interdire' doivent tout les deux être implémentés pour fournir
le niveau de flexibilité requis par le contrôle d'accès des hôtes.
8.12.2 OpérateursEn raison des pouvoirs qui leur
sont accordés , le don des privilèges d'opérateurs à une personne turbulente
peut avoir des conséquences désastreuses sur le bien-être du réseau IRC en
général. C'est pourquoi l'acquisition de ces pouvoirs ne doit pas être facile.
La configuration actuelle nécessite deux mots de passes, bien que l'un d'entre
eux soit généralement facile à trouver. L'enregistrement des mots de passe
d'opérateur dans le fichier de configuration est préférable à leur codage en
dur, et ils doivent être sauvegardé dans un format codé (par exemple en
utilisant crypt(3) d'Unix) afin de rendre les vols plus difficiles.
8.12.3 Autorisation des connections de
serveursL'interconnexion de serveurs n'est pas une chose triviale : une
mauvaise connection peut avoir un gros impact sur l'utilité d'IRC. C'est
pourquoi chaque serveur doit avoir une liste des serveurs sur lesquels il peut
se connecter, et de ceux qui peuvent se connecter à lui. En aucune manière un
serveur ne doit accepter arbitrairement une connection d'hôte en tant en
serveur. En plus de la liste des serveurs qui peuvent et qui ne peuvent pas se
connecter, le fichier de configuration doit aussi contenir le mot de passe et
les autres caractéristiques de ce lien.
8.12.4 AdminPour fournir des réponses valides et
précises à la commande ADMIN (voir section 4.3.7), le serveur
doit trouver tous les détails appropriés dans le fichier de configuration.
8.13 Appartenance à un canal.Le serveur actuel
autorise tout utilisateur enregistré localement à accéder jusqu'à 10 canaux
différents. Il n'y a pas de limites imposées aux utilisateurs non-locaux, si
bien que le serveur reste (raisonnablement) cohérent avec les autres serveurs
pour ce qui est de l'appartenance à un canal.
|