Identification
Nous souhaitons identifier les logiciels tournant sur certains ports. Plutôt que de nous contenter d'ouvrir une connexion, nous allons maintenant retourner une valeur indiquant la ligne d'entête renvoyée par le service sur lequel nous nous sommes connecté si elle arrive dans un temps raisonnable :
$ cargo run -- ping -o www.free.fr,smtp.free.fr,imap.free.fr,ftp.free.fr 21,25,80,143,587
ftp.free.fr:21 is open: 220 Welcome to ProXad FTP server
imap.free.fr:143 is open: * OK IMAP4 ready
smtp.free.fr:25 is open: 220 smtp3-g21.free.fr ESMTP Postfix
smtp.free.fr:587 is open: 220 smtp3-g21.free.fr ESMTP Postfix
www.free.fr:80 is open
Le résultat est cohérent : le serveur FTP (port 21), le serveur IMAP (port 143) et les serveurs SMTP (port 25 et port 587) s'annoncent spontanément. Par contre le serveur HTTP (port 80) n'enverra une réponse que si on envoie une requête.
- Ajoutez un type
scanner::IdentificationResult
contenant trois alternatives :WelcomeLine(String)
,NoWelcomeLine
etConnectionRefused
. - Écrivez une fonction asynchrone
scanner::net::welcome_line()
qui prend untokio::net::TcpStream
en paramètre et qui renvoie unIdentificationResult
contenant soitWelcomeLine(…)
si le serveur a envoyé une ligne de bienvenue dans la première seconde, ouNoWelcomeLine
dans tous les autres cas.
Bien entendu, si on n'a jamais obtenu de TcpStream
car la connexion a échoué, on renverra ConnectionRefused
.
Vous pouvez enrichir votre stream de capacités de lecture plus puissantes en l'encapsulant dans un tokio::io::BufReader
qui implémente le trait tokio::io::AsyncBufRead
. Ce trait est étendu par le trait d'extension tokio::io::AsyncBufReadExt
. On notera également qu'il est facile d'éliminer d'éventuels caractères de fin de ligne parasites avec des fonctions existantes de str
.
-
Modifiez la fonction
tcp_ping()
pour qu'elle appellewelcome_line()
si la connexion au serveur distant réussi. Le résultat devra être modifié pour renvoyer unIdentificationResult
à la place dubool
précédemment utilisé. -
Modifiez vos fonctions
tcp_ping()
,tcp_ping_many()
ettcp_mping()
pour propager de la même manière ce résultat. -
Modifiez le programme principal pour qu'il affiche la ligne d'identification quand elle est disponible comme dans l'exemple ci-dessus.