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

Répondre à