Add Transport part
This commit is contained in:
parent
93b5cc567d
commit
d942180d6c
1 changed files with 99 additions and 159 deletions
|
@ -7,189 +7,129 @@ categories: ["Réseaux et protocoles", "Cours"]
|
|||
mathjax: true
|
||||
---
|
||||
|
||||
On parle ici des protocoles utilisé par les applications comme *SMTP*, *HTTP*,
|
||||
*DNS*, *IMAP*, etc. On se place au niveau **application** du modèle *TCP* ou de
|
||||
l'ensemble des couches 4 à 7 du modèle *OSI*. Ici il n;est pas question pour les
|
||||
dévellopeur de programmer pour le cœur de réseau, mais pour la périphérie.
|
||||
Nous parlons ici de la communication entre deux processus dans la couche 4 du
|
||||
OSI. Les messages sont découpés et insérés dans des **segments** . Le
|
||||
destinataire va ensuite réassemblé ces segments et pour les passer à la couche
|
||||
applicative.
|
||||
|
||||
## Modèle client-serveur
|
||||
La couche transport ajoute les entêtes aux message qui lui sont transmis.
|
||||
|
||||
Comme indique le titre, nous avons deux types d'acteur :
|
||||
Deux protocoles principaux compose cette couche : **TCP** pour *Transmission
|
||||
Control Protocol* et **UDP** pour *User Datagram Protocol*.
|
||||
|
||||
* **le serveur**: il est toujours actif avec une adresse IP fixe. La plupart du
|
||||
temps il est dans un *datacenter*;
|
||||
* **le client**: il communique avec le serveur uniquement lorsqu'il en a
|
||||
besoin. Le client n'a pas besoin d'adresse IP fixe. C'est lui qui contacte le
|
||||
serveur qui en reponse lui répondra. Les clients n'échangent pas entre eux.
|
||||
UDP est un protocole simple, sans *overhdead* mais aussi sans contrôle et
|
||||
sans connexion.
|
||||
|
||||
## Modèle P2P
|
||||
TCP est plus complexe, il intègre des contrôles (congestion, ordre des segments,
|
||||
flux). C'est aussi un protocole connecté.
|
||||
|
||||
Ici les clients peuvent aussi faire office de serveurs. Les équipements
|
||||
terminaux sont aussi **connectés entre eux**. C'est une architecture
|
||||
*distribuée* et *auto-scalable*. La gestion des **peers** est complexe.
|
||||
## Multiplexage, démultiplexage
|
||||
|
||||
Dans ce cas il y a deux processus (un serveur et un client) sur la même machine.
|
||||
|
||||
## Communication inter-processus
|
||||
|
||||
Dans le cadre de programmes qui s'exécutent sur un même équipement, on utilisera
|
||||
les mécanismes de communication inter-processus.
|
||||
|
||||
Avec des processus répartis sur des machines differentes, les messages sont
|
||||
acheminées via le réseau. On utiliseta alors les mécanismes de *sockets*.
|
||||
|
||||
## Les sockets
|
||||
|
||||
C'est une passerelle entre les couches transport et applications. C'est une
|
||||
porte d'envoi / réception de données pour les processus.
|
||||
|
||||
## Adressage
|
||||
|
||||
La couche réseaux (3) esr représentée par une adresse IP 32 bis en v4 (et 128 en
|
||||
v6). Mais cette adresse ne suffit pas pour identifier le processus qui demande
|
||||
les données. Il faut alors le **numéro de port**.
|
||||
|
||||
Ces numéros vont de 0 à 65535, les 1024 premiers sont normalement réservés pour
|
||||
les serveurs, le reste pour les clients.
|
||||
|
||||
## Besoins spécifiques des applications
|
||||
|
||||
Les applications n'ont pas toutes les mêmes besoins en ce qui concerne les
|
||||
données envoyées ou reçues via un réseau informatique
|
||||
|
||||
La VoIP, ou encore le streaming audio / vidéopeuvent se passer des **contrôles
|
||||
d'intégrité** par exemple. mais la VoIP elle nécessite d'utiliser des
|
||||
communication **temps réel** (ou de s'en approcher) tout comme le jeu en ligne.
|
||||
|
||||
## La couche transport
|
||||
|
||||
Nous avons ici deux protocoles utilisés:
|
||||
|
||||
### TCP
|
||||
|
||||
C'est un protocole avec connexion qui vise avant tout **la fiabilité** :
|
||||
contrôle de flux, gestion de la congestion, réordonancement des paquets. Avant
|
||||
d'acheminer des données, il est nécessaire de lancer une connexion en 3 étapes
|
||||
(`SYN`, `SYN-ACK`, `ACK`). Il est aussi nécessaire de mettre fin explicitement
|
||||
à la connexion (`FIN`). Cependant il **n'y a pas de gestion du timing** ni de
|
||||
**sécurité**.
|
||||
|
||||
#### La sécurité dans TCP
|
||||
|
||||
Comme nous l'avons vu il n'y a pas de gestion de la sécurité dans *TCP*. Mais il
|
||||
existe une couche intermédiaires entre les couches *application* et *transport*
|
||||
: TLS pour **Transport Layer Security**.
|
||||
|
||||
*TLS* se charge de l'authentification, du chiffrement, et du contrôle de
|
||||
l'intégrité.
|
||||
|
||||
### UDP
|
||||
|
||||
Ici il n'y a pas de gestion de fiabilité (ordre, sommes de contrôle,
|
||||
acquittement, etc.). En contrepartie il y a peu *d'overhead*, il est donc adapté
|
||||
our la VoIP par exemple. Il est aussi plus simple à implémenter et supporte le
|
||||
*multicast* et le *broadcast*.
|
||||
|
||||
## Quelques protocoles
|
||||
|
||||
### HTTP
|
||||
|
||||
C'est le protocole utilisé pour le **web**, il se base sur *TCP* et les
|
||||
mécanismes de connexions sous-jacent. Il est de type client - serveur:
|
||||
|
||||
* client: *User Agent*, le navigateur web;
|
||||
* serveur: serveur HTTP comme Apache ou Nginx.
|
||||
|
||||
Le serveur stocke des objets (fichiers HTML, images, vidéos etc.)
|
||||
|
||||
Il existe deux type de connexions HTTP :
|
||||
|
||||
* persistente: 1 connexion pour transférer plusieurs objets;
|
||||
* non persistente: 1 connexion pour tranférer un objet.
|
||||
|
||||
#### La requête
|
||||
|
||||
Elle emmane du client à destination du serveur, la requête est formatée en
|
||||
ASCII, elle contient une requête suivi d'élément d'entête:
|
||||
Tous les segments passent par le même chemin, il faut donc passer par une
|
||||
opération de multiplexage (emetteur) et démultiplexage (recepteur).
|
||||
|
||||
```
|
||||
GET https://ent.u-bordeaux.fr HTTP/2\r\n
|
||||
+-----------+ +------------------+ +---------------------+
|
||||
| processus | o==> | couche transport | o==> | process de l'entête | o=
|
||||
+-----------+ +------------------+ +---------------------+
|
||||
|
||||
+-----------+
|
||||
=> | couche IP |
|
||||
+-----------+
|
||||
```
|
||||
|
||||
Ici on demande `https://ent.u-bordeaux.fr` en HTTP version 2. Les entêtes peuven
|
||||
contenir les langies acceptés par le client par exemple.
|
||||
Le message envoyé par le processus passe par la couche transport qui y ajoute
|
||||
l'entête. Le segnemt qui en résulte est esuite envoyé à la couche IP
|
||||
|
||||
#### La réponse
|
||||
Sur le système du destinataire, l'adresse IP et les ports sont utilisés pour
|
||||
déterminer la bonne socket à utiliser. Chaque socket est alors un tuple de 4
|
||||
éléments:
|
||||
|
||||
Elle contient le code de retour, les entêtes de réponse ainsi que le contenu. La
|
||||
réponse peut être conditionnée à la modification de la ressource demandée via un
|
||||
*conditionnal GET*. L'entête de la demande contient le champs
|
||||
`If-Modified-Since`. Le serveur peut alors répondre avec un code `304`
|
||||
`Not-Modified` et le navigateur utilisera la version dans son cache.
|
||||
* IP source
|
||||
* IP destination
|
||||
* port source
|
||||
* port destination
|
||||
|
||||
#### Amélioration du protocole
|
||||
## UDP dans le détail
|
||||
|
||||
La verion 2 de HTTP permet de découper les ressources demandées en *chunk* et de
|
||||
réaliser des envois entrelacés. Ainsi les gros fichiers ne pénalisent pas le
|
||||
transfert des plus petits (mécanismes de `first come first served*.
|
||||
|
||||
La version 3 propose d'utiliser les protocole UDP et QUIC. Il propose de gérer
|
||||
la réupération de paquets perdus (hé oui, il utlise UDP), il propose aussi la
|
||||
gestion de la congestion et plus de sécurité (QUIC).
|
||||
|
||||
### DNS
|
||||
|
||||
C'est le protocole chargé de la résolution des noms de domaines (et des
|
||||
résolutions inverses). Il fait le lien entre les adresses IP et les noms de
|
||||
domaines. C'est **une base de donnée distribuée** our éviter le *single point
|
||||
of failure*
|
||||
|
||||
La base de données est hiérarchisée : `Root server` -> `Top level domain` ->
|
||||
`authoritative server` -> `recursive resolver`.
|
||||
|
||||
|
||||
Deux types de requêtes:
|
||||
|
||||
* **itérative**: le résolveur a la charge de la requête et demande les
|
||||
informations du *root* jusqu'au serveur *authoritative*;
|
||||
* **recursive**: chaque serveur est responsable de sa réponse. La requête va
|
||||
ainsi passer de serveur en serveur et faire le chemin inverse jusqu'à revenir
|
||||
au client.
|
||||
|
||||
#### Les enregistrement DNS et les messages
|
||||
|
||||
Il sont au format RR *Ressource Record*:
|
||||
C'est un protocole non orienté connexion, en mode best effort. Il est donc moins
|
||||
fiable mais comme nous l'avons dit sans overhead. Les segments sont indépendants
|
||||
les un des autres. C'est un protocole particulièrement adapté pour le streaming,
|
||||
la VoIP, les jeux en ligne. Tout ces usage qui privilégient la vitesse de
|
||||
transmission. Il est aussi utilisé pour HTTP3 et d'autres protocoles tolérants à
|
||||
la panne. La fiabilité **est alors implementée dans la couche applicative**.
|
||||
|
||||
```
|
||||
<nom> <valeur> <type> <TTL>
|
||||
0 32
|
||||
+-----------------+------------------+
|
||||
| source port | destination port |
|
||||
+-----------------+------------------+
|
||||
| checksum | lenght |
|
||||
+-----------------+------------------+
|
||||
| D A T A |
|
||||
| |
|
||||
| ... |
|
||||
```
|
||||
|
||||
Les messages du serveur vers le client contiennent le nombre de question, le
|
||||
nombre de réponse et enfin les réponses.
|
||||
Le checksum est un contrôle élémentaire du paquet reçu afin de vérifier les
|
||||
paquets reçus. Cependant **une erreur peut être non détetée**.
|
||||
|
||||
## Retour sur les sockets
|
||||
## TCP dans le détail
|
||||
|
||||
Comme nous l'avons vu elle serve de point de liaisons entre les applications et
|
||||
la couche transport. Elle sont créees par le système.
|
||||
C'est un protocole point à point fiable, avec ordre (chaque paquet a un ordre
|
||||
précis dans la file), avec acquitement (`ACK`), avec gestion des flux et de ala
|
||||
congestion.
|
||||
|
||||
Pour la création de socket UDP :
|
||||
|
||||
```c
|
||||
mysock = socket(AF_INET, SOCK_DGRAM);
|
||||
mysock.rcevfrom();
|
||||
mysock.sendto();
|
||||
bind(mysock, &addr, sizeof(addr));
|
||||
C'est un protocole orenté connexion (`accept()`), l'établissement d'une
|
||||
connexion se fait au moyen d'une poignée de main en trois étapes `SYN` ->
|
||||
`SYN-ACK` -> `SYN`
|
||||
|
||||
L'entête est aussi plus complexe:
|
||||
|
||||
```
|
||||
0 15 32
|
||||
+-------------------------------+-------------------------------+
|
||||
| source port | destination port |
|
||||
+-------------------------------+-------------------------------+
|
||||
| numéro de séquence |
|
||||
+---------------------------------------------------------------+
|
||||
| numéro de d'acquitement |
|
||||
+---------------+-+-+-+-+-+-+-+-+-------------------------------+
|
||||
| header size | |E| |A| |R|S|F| receive window |
|
||||
+---------------+-+-+-+-+-+-+-+-+-------------------------------+
|
||||
| checksum | destination port |
|
||||
+-------------------------------+-------------------------------+
|
||||
| options (taille variable) |
|
||||
+---------------------------------------------------------------+
|
||||
```
|
||||
|
||||
C'est relativement simple car il n'y a pas de connexion.
|
||||
Le numéro d'acquitement contient le numéro de séquence reçue plus la taille su
|
||||
segment. Dans ce même paquet, le numéro de séquence est le numéro d'`ACK`.
|
||||
|
||||
Pour TCP c'est un peu plus complexe:
|
||||
L'`ACK` est *cumulatif*, il couvre les acquitement précédents.
|
||||
|
||||
```c
|
||||
mysock = socket(AF_INET, SOCK_STREAM);
|
||||
mysock.listen();
|
||||
mysock.connect(addr, port);
|
||||
Le *fast retransmit* permet la reduction du temps de retransmission. Le
|
||||
mécanisme de double aquitement permet d'accélérer lea retransmisison de segments
|
||||
perdus. Lorsque l'emmeteur reçoit le même acquitement en double, alors il
|
||||
renvoi le paquet suivant correpondant.
|
||||
|
||||
// Accept connection result a new one!
|
||||
newsocks = mysock.accept();
|
||||
```
|
||||
### Contrôle de flux
|
||||
|
||||
TCP dispose d'une **receive window** qui représente la quantité de données
|
||||
pouvant être reçue à un instant T. Ce mécanisme permet d'éviter que le réseaux
|
||||
n'envoie plus de données que la capacité de traitement du terminal.
|
||||
|
||||
Les donnees reçues par la socket sont stockées dans une structure `rcvbuffer`,
|
||||
la *receive window** correspond à la qantité de données disponible dans ce
|
||||
buffer.
|
||||
|
||||
### Contrôle de la congestion
|
||||
|
||||
L'approche est simple: on augmente le taux d'envois jusqu'à constater de pertes
|
||||
de paquets, alors on le diminue. Le principe est le suivant:
|
||||
|
||||
* **additive increase**: on agmente le taux de 1
|
||||
* **multiplicative decrease**: on divise le taux par 2 lorsque l'on reçoit
|
||||
trois fois le même numéro d'`ACK` (sinon on diminue de 1 la *Maximum Segment
|
||||
Size* en cas de détection de perte par timeout)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue