Add Transport part

This commit is contained in:
Yorick Barbanneau 2024-03-06 22:19:26 +01:00
parent 93b5cc567d
commit d942180d6c

View file

@ -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)