On Sun, Sep 12, 2004 at 11:17:49AM +0200, Arnaud Burlet wrote: > et dans le cas d'un serveur dns qui fait (admettons) deux requ�tes simultan�es > (depuis 2 threads ou process diff�rents) vers le m�me serveur dns, on a le > cas : > 1.2.3.4:53 <----->> 4.3.2.1:53 (pour une premiere requ�te) > 1.2.3.4:53 <----->> 4.3.2.1:53 (pour une seconde requ�te) > est-ce possible ?
M�me si le serveur et le clients sont multi-thread (et sous UNIX ils seront plut�t single-threaded et multiplex�s avec select(2)), un socket donn� (bind(2) � un port local) est un descripteur qui d�livre des donn�es (TCP) ou des donn�es d�limit�es par datagramme (UDP) de fa�on s�quentielle (voir plus bas sur l'atomicit� de write(2) et de send(2) selon POSIX). Il n'y aura jamais simultan�it� pour un seul socket. Il y aura peut-�tre un `dispatcher' au niveau du serveur DNS, s'il est multithread�: la r�ception sera single-threaded, le traitement parall�le. Si le client utilise un port statique (genre 53) plut�t qu'un port fant�me > 1023, il doit g�rer en interne une table de question et g�rer les r�ponses en fonction. C'est le cas de BIND9. Un client peut d'ailleurs s'attendre � recevoir une r�ponse ne provenant pas du bon serveur, ou correspondant � aucune question donn�es, pour diverses raisons (p.ex. attaque). Notamment il ne devrait pas enregistrer dans son cache des r�ponses � des questions non pos�es. Certaines versions du serveur DNS pour Microsoft Windows avaient ce probl�me (et je crois aussi d'anciennes versions 4 de BIND), qui s'appelle `cache poisoning'. Pour TCP, c'est diff�rent. Une requ�te sera pr�c�d�e d'une ouverture � 3 phases de connexion, et la r�ponse suivie d'une fermeture de connexion. En th�orie on peut donc effectuer deux op�rations successives dans la mesure o� la connexion est bien ferm�e correctement entre deux. > - deux clients qui se connectent � ce serveur avec chacun le m�me port TCP > comme source. impossible (voir plus bas). > Tout fonctionne jusqu'� l'appel connect() du deuxi�me client qui �choue, errno > indiquant : "Cannot assign requested address". Il y a ici un bind(2) implicite qui �choue forc�ment. Un seul processus peut bind(2)er sur tuple (port local, adresse locale). Le seul cas qui peut aboutir � un partage d'un socket: si ce processus lance des fils (fork(2)), ils peuvent partager le socket, mais il y aura s�rialisation (write(2) ou send(2) sont atomiques: l'atomicit� signifie, sous POSIX, que s'il n'est pas possible d'envoyer p.ex. 1024 bytes maintenant, on envoie ce qu'on peut � TCP et write(2) retourne moins de bytes que pr�vu. Il faut donc boucler. Cela est vrai pour tous les p�riph�riques de type caract�re, les tty, etc). > Ce n'est pas clair dans ce message d'erreur, mais on peut en d�duire qu'une > connection est bien identifi�e par > (addresse source, adresse destination; port source, port destination) En fait ici, ce qui coince c'est la partie locale (port source, adresse source). > Si je reviens � mon exemple en-dessus, un serveur dns a donc un m�canisme qui > emp�che ce type de situation, ou qui les d�tecte ? Cette situation ne se produit pas. Pour ajouter � la complexit�, au niveau du serveur il y a un m�canisme qui emp�che la r�utilisation d'un socket pendant un d�lai (p.ex. 2 minutes), sauf si une option particuli�re (SO_REUSEADDR) apparue dans SYSVR4 si je me souviens bien est sp�cifi�e pour le socket. La raison de ce m�canisme est pour permettre, si je me souviens bien, des cas �tranges de fermeture de connexion incorrects. Le d�lai est quelque chose comme 2 * le temps de vie du segment. Il y a d'ailleurs un �tat, pour le serveur, dans lequel la paire de connexion reste toujours dans le syst�me (voir netstat): si le client ne ferme pas correctement (pour �viter la perte de donn�es). La plupart des syst�mes violent le standard TCP et ont �galement un timeout � ce niveau pour �viter des attaques de type DoS. _______________________________________________ gull mailing list [EMAIL PROTECTED] http://lists.alphanet.ch/mailman/listinfo/gull
