M1 Informatique Réseaux Cours 6 Couche Transport : TCP et UDP Notes de Cours LA COUCHE TRANSPORT CONTRÔLE LE FLOT DE DONNEES TRANSMISES par la couche Réseau dans le but d offrir des garanties de service aux couches supérieures. Ce contrôle s opère uniquement en bord de réseau, au niveau des correspondants. 1 Introduction 1.a "Vous êtes Ici" 7 OSI Application TCP/IP Application 6 5 Presentation Session Not present in the model 4 3 2 1 Transport Network Data link Physical Transport Internet Host-to-network 1.b Objectifs En se basant sur la couche réseau (transmission de datagramme d un point à l autre du réseau) offrir une certaine qualité de service. Pour IP Sans connexion : Ex : UDP/IP E. Godard http://www.lif.univ-mrs.fr/~egodard/ens/reseaux/
Orienté connexion : Ex : TCP/IP 1.c Espace de Nommage : les Ports Pour pouvoir gérer ( = distinguer au niveau application) plusieurs envois simultanés entre deux même machines, il faut augmenter l espace de nommage. => les ports : entiers sur 16 bits L espace de nommage ajoute ses ports aux noms IP. Ex : 147.64.94.233 :9000 Une connexion TCP est donc identifiée par quatre paramètres : adresse IP et port d origine adresse IP et port de destination 1.d Ports Classiques Traditionnellement, on associe un numéro de port particulier pour chaque type de serveurs : 20 ftp-data 21 ftp transfert de fichier 22 ssh connexion à distance encryptée 23 telnet connexion à distance 25 smtp envoi de courrier électronique 80 http serveur web 110 pop3 consultation de courrier électronique 194 irc discussion 443 https connexion sécurisé à un serveur web 993 imaps 6667 ircd Dans /etc/services : standardisation IANA. NB les ports < 1024 ne peuvent être utilisés que par le super-utilisateur. 1.e UDP User Datagram Protocol Envoi de datagramme : pas d assurance que le paquet sera reçu pas d accusé de réception vérification d intégrité 1.f Entete UDP 32 Bits Source port UDP length Destination port UDP checksum 2
1.g Utilisation d UDP UDP est utilisé pour des protocoles ayant des exigences très spécifiques qui délèguent la qualité de service à une couche supérieure des protocoles simples par exemple, interrogation de base de données très simples NTP : Network Time Protocol ( synchronisation fine d horloge) RTP : Real Time Protocol DNS : Domain Name Server 1.h Utilisation d UDP : DNS Rappel : Résolution des noms IANA en adresses IP (v4 **et* v6) Table locale Interrogation d une base de données distante : RFCs 1983 : RFC 882 - RFC 883 1987 : RFC 1034 - RFC 1035 1994 : RFC 1591 2011 : RFC 6195 port : 53 format : pas plus de 512 octets (sinon passer en TCP) requête réponse 1.i Utilisation d UDP : RTP Protocole utilisé par les applications temps réels Ex : flux vidéo User space Multimedia application RTP Ethernet header IP header UDP header RTP header OS Kernel Socket interface UDP IP Ethernet (a) RTP payload UDP payload IP payload Ethernet payload (b) 1.j TCP Transmission Control Protocol envoi et réception de données en mode connecté : 3
contrôle de la connexion : synchronisation vérification d intégrité Remarques Ces vérifications d intégrités ne sont-elles pas superflues étant donnés les CRCs de la couche liaison? => Non! certaines erreurs subsistent : When The CRC and TCP Checksum Disagree Jonathan Stone, Craig Partridge SIGCOMM 2000 1.k Entête TCP 32 Bits Source port Destination port Sequence number Acknowledgement number TCP header length U R G A C K P S H R S T S Y N F I N Window size Checksum Urgent pointer Options (0 or more 32-bit words) Data (optional) Signification des champs : Port source Valeur du port source Port destination Valeur du port destination Numéro de séquence Numéro de séquence du premier octet de ce segment Numéro d acquittement Numéro de séquence du prochain octet attendu Taille de l en-tête Taille de l en-tête en mots de 32 bits (les options font partie de l en-tête) Drapeaux Réservé Réservé pour un usage futur ECN Signale la présence de congestion, voir RFC 3168 URG Signale la présence de données urgentes (cf Pointeur d urgence) ACK Le paquet est un accusé de réception PSH Données à passer immédiatement à la couche supérieure/l application (vs tampons) RST Rupture de la connexion (anormal, pas une terminaison propre) SYN Etablissement de connexion FIN Demande la fin de la connexion (dans ce sens) Fenêtre Taille de fenêtre demandée Checksum Somme de contrôle calculée sur l ensemble de l en-tête TCP et des données, mais aussi sur un pseudo en-tête (extrait de l en-tête IP) (=> TCP/IP) 4
Pointeur de données urgentes Position relative des dernières données urgentes Options Facultatif Remplissage : Zéros ajoutés, si nécessaire, pour aligner les champs suivants du paquet sur 32 bits Données Données transmises par l application 1.l Fonctionnement de TCP Rappelons ce que doit assurer TCP : Établissement de la connexion : Poignée de main en trois temps Transport fiable des données Tout paquet doit arriver => accusé de réception, retransmission Tout paquet doit arriver dans l ordre => numérotation des segments Gestion de la déconnexion : Poignée de main de déconnexion 1.m Poignée de main Avant de pouvoir émettre des données, il faut "synchroniser" (les paramètres) des client et serveur. client : Envoi d un segment SYN serveur : Accusé de réception et mise en place de la session SYN,ACK client : Accusé de réception du segment émis par le serveur : ACK 5
1.n Transmissions des Données Numéro de segments : SEQ Accusé de réception pour chaque segment reçu lourd fenêtre d accusés de réception Gestion des tampons avec des fenêtres : WIN 1.o Fenêtres d Emissions Application does a 2K write Sender Receiver Receiver's buffer 0 4K Empty 2K SEQ = 0 ACK = 2048 WIN = 2048 2K Application does a 2K write 2K SEQ = 2048 Full Sender is blocked Sender may send up to 2K ACK = 4096 WIN = 0 ACK = 4096 WIN = 2048 Application reads 2K 2K 1K SEQ = 4096 1K 2 K La poignée de main ayant été effectuée, la transmission de données peut commencer. Celle-ci peut être à l initiative du serveur ou bien du client (cela dépend du protocole applicatif). 1. l émetteur envoie 2 ko de données issues de la couche application, 2. le récepteur les stocke dans un tampon du système d exploitation de taille 4 ko, 3. le récepteur envoie un accusé de réception avec l indication qu il possède encore 2 ko de libre dans son tampon, 4. l émetteur reçoit encore 2 ko depuis son application, comme cela est inférieure (ou égal) à la valeur de WIN, il les envoie. 5. le récepteur stocke ces données dans le tampon, qui est maintenant rempli, 6
6. le récepteur envoie un accusé de réception avec l indication qu il ne possède plus de mémoire libre dans son tampon, 7. depuis l émission précédente, l émetteur ne doit plus rien émettre 8. Quand l émetteur reçoit une indication de fenêtre de 2 ko (suite à une lecture (partielle) du tampon par l application côté récepteur), il peut de nouveau émettre (mais pas plus de 2 ko). 9. l émetteur envoie 1 ko. 1.p Terminaison d une Session Comme la poignée de main : Envoi de : FIN Accusé de réception : FIN,ACK Accusé de réception de l accusé précédent : ACK 1.q Etats d une Connexion TCP (Step 2 (Start) CONNECT/SYN (Step 1 of the 3-way handshake) CLOSED CLOSE/ LISTEN/ CLOSE/ SYN/SYN + ACK of the 3-way handshake) LISTEN SYN RCVD RST/ SYN/SYN + ACK SEND/SYN (simultaneous open) SYN SENT (Data transfer state) CLOSE/FIN ACK/ ESTABLISHED SYN + ACK/ACK (Step 3 of the 3-way handshake) CLOSE/FIN (Active close) FIN/ACK (Passive close) FIN WAIT 1 FIN/ACK CLOSING CLOSE WAIT ACK/ ACK/ CLOSE/FIN FIN WAIT 2 FIN + ACK/ACK FIN/ACK TIME WAIT LAST ACK (Timeout/) CLOSED ACK/ (Go back to start) 7
Les états des sockets (cf sous-section 2.a) sont visibles avec netstat. 1.r Sécurité de TCP De nombreux problèmes de sécurité sont connus : écoute usurpation de connexion vol de session ( prédictibilité de SEQ ) dénis de service... 1.s Déni de Service Un déni de service est une attaque qui consiste à rendre indisponible un service réseau. Exemple : inondation de paquet SYN. Un protocole est susceptible de déni de service en général si celui-ci est très dissymétrique (en puissance de calcul, en allocation mémoire,...). Rq : Les dénis de service distribués sont différents : faire sauter le standard. 1.t Retour sur le NAT/PAT La translation d adresse d un réseau privé vers Internet se fait par association de couple adresse privée / port local avec un port de la passerelle. Cette association peut se faire dynamiquement (à l envoi du paquet SYN en TCP). (figures wikipedia commons ) 8
Cela pose problème pour deux clients derrière leur NAT respectifs, et qui souhaite établir une communication. En UDP : technique STUN pour connaître l IP routée En TCP : bien plus problématique nombreuses solutions. standardisation en cours. 1.u Conclusion Provisoire Deux moyens important de communiquer : non fiable : UDP/IP connecté et fiable : TCP/IP presque tout le trafic internet mais pénurie adresses IPv4 technique NAT résoud en partie le problème précédent mais impose de sérieux problèmes de connectivité de bout en bout 1.v Problèmes et Evolutions Ces protocoles de transport sont déployés depuis plus de 25 ans, certaines évolutions sont cependant proposées : TCP sur des réseaux sans fil la perte de paquet en TCP est imputée à la congestion, et un mécanisme de diminution de la fenêtre d envoi est mis en place dans ce cas. Or sur les réseaux sans-fil, des pertes se produisent pour des raisons toutes autres. Cela conduit à une sous-utilisation de ces réseaux. De nombreuses solutions ont été proposées (intervenant sur différentes couches). TCP Fast Open accélérer les communications TCP en ne refaisant pas de poignée de main en cas de communication successives (utilisation d un cookie cryptographique). 2 Programmation Réseaux 2.a L Interface de Programmation socket Créée pour Unix BSD Orienté client-serveur Interface unifiée et multi-protocoles Appels systèmes bloquants ou non-bloquants Fonctionnement : 9
Serveur bind listen accept send recv. shutdown Client connect recv send. shutdown A voir en TP 2.b Bibliothèques C #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> 2.c Créateur int socket(int domaine, int type, int protocole) renvoie : descripteur de la socket, -1 en cas d erreur domaine : PF_UNIX, PF_INET, PF_INET6, PF_IPX, PF_X25, PF_PACKET,... type : SOCK_DGRAM, SOCK_STREAM, SOCK_RAW,... protocole :..., 0 pour le protocole par défaut de domaine/type 2.d Fermetures int close(int sockfd) en TCP, vide le tampon d émission int shutdown(int sockfd, int sens) ferme la socket de type SOCK_STREAM dans le sens SHUT_RD : réception SHUT_RW : envoi SHUT_RDRW : réception et envoi 2.e Attachement à Une Adresse int bind(int sockfd, const struct sockaddr *adresse, socklen_t taille) sockfd est associée à adresse codée sur taille octets (dans un struct idoine) pseudo-programmation orientée objet Renvoie : -1 en cas d erreur 10
2.f Ouverture de la Socket int listen(int sockfd, int attente) ouverture de sockfd vers l extérieur attente définit la taille de la file d attente de gestion des connexions. Parfois limitée par le système à SOMAXLOG=128, LINUX 5, BSDs Renvoie : -1 en cas d erreur 2.g Gestion des Connexions Clientes int accept(int sockfd, struct sockaddr *adresse, socklen_t *taille) Renvoie : le nouveau descripteur de socket correspondant à le première connexion de la file d attente de sockfd (de type SOCK_STREAM). -1 en cas d erreur, et errno contient le code d erreur correspondant. adresse contient l adresse du client, stockée sur taille octets. Au retour, taille vaut le nombre d octets réellement utilisés. Si adresse vaut NULL, la structure n est pas renseignée. bloquant, sauf indication contraire. 2.h Connection à un Serveur int connect(int sockfd, const struct sockaddr *adresse_s, socklen_t taille) tente de connecter sockfd à adresse_s, stockée sur taille octets. en non connecté, adresse_s contient l adresse de réception par défaut et l adresse d émission. L association peut être renouvelée. en connecté, établit la connexion avec le serveur nommé adresse_s Renvoie : -1 en cas d erreur 2.i Options de la Socket int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) Niveau socket (SOL_SOCKET) SO_BROADCAST : autorise l envoi sur des adresses de diffusion (interdit par défaut) SO_KEEPALIVE : maintenir une connexion 11
SO_REUSEADDR : suppression d un délai d attente pour réutilisation rapide d un port (risqué) SO_RECVBUF : taille maximale du tampon de réception SO_SENDBUF : taille maximale du tampon d émission Niveau TCP (IPPROTO_TCP) TCP_NODELAY : envoi des données sans mise en tampon TCP_MAXSEG : taille maximale des segments TCP 2.j Rappel : Appels Système Un descripteur de socket est un descripteur de fichier classique, ssize_t write(int fd, const void *tamp, size_t taille) ssize_t read(int fd, void *tamp, size_t taille) utilisation de tampons int send(int s, const void *msg, size_t len, int drapx) int recv(int s, void *msg, int len, unsigned int drapx) drapx (en général 0) peut être : MSG_OOB : pour les messages hors bandes MSG_PEEK : lire les données sans les enlever de la file MSG_WAITALL : demande que l opération de lecture soit bloquée jusqu à ce que la requête complète soit satisfaite. MSG_DONTROUTE : est utilisé pour empêcher la transmission d un paquet vers une passerelle... 2.k Utilitaires : Conversion de Noms et Adresses struct hostent* gethostbyname(char* nomicann) struct hostent * gethostbyaddr(const void *adresse, int longueur, int type) => obsolètes (POSIX 2001) Il faut désormais utiliser int getaddrinfo(const char * noeud, const char * service, const struct addrinfo *indic, struct addrinfo ** reso); int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); 2.l struc addrinfo 12
struct addrinfo { int ai_flags; /* drapeaux */ int ai_family; /* Internet, ATM,... */ int ai_socktype; /* avec ou sans connexion */ int ai_protocol; /* TCP, UDP,... */ size_t ai_addrlen; /* taille struct sockaddr */ struct sockaddr *ai_addr; /* adresse socket */ char *ai_canonname; /* nom canonique */ struct addrinfo *ai_next; /* enregistrement suivant */ }; Cf exemples. 2.m Utilitaires : Conversion d Implémentation des Entiers Sur un hôte, les entiers peuvent être implémentés de manières différentes (en fonction de l architecture du processeur) : grand-boutiste petit-boutiste Sur le réseau, les entiers sont toujours transmis de la même manière. Pour être portable, il faut utiliser des fonctions de conversions hôte/réseau : short htons(short) et long htonl(long) short ntohs(short) et long ntohl(long) 2.n IPv6 Il faut une (nouvelle) structure de données adaptée : struct sockaddr_in6 { sa_family_t sin6_family; /* AF_INET6 */ in_port_t sin6_port; /* port number */ uint32_t sin6_flowinfo; /* IPv6 flow information */ struct in6_addr sin6_addr; /* IPv6 address */ uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */ }; 2.o Double Compatibilité Comment écrire un serveur qui écoue en IPv4 et en IPv6? deux processus (un par protocole) un seul processus bloquant vs non-bloquant => double pile 13
2.p Implémentation Double pile il est possible d utiliser une double pile avec in6addr_any struct sockaddr_in6 sa6; sa6.sin6_addr = in6addr_any; //ecoute en IPv6 et IPv4 Les adresses IPV4 apparaissent en ::ffff:<adr. IPv4> NB. N existe pas pour tous les systèmes d exploitation. Et peut-être contrôlé par l option IPV6_V6ONLY 2.q Documentation man socket man 2... man 7 socket man unix man ip man tcp... 2.r Programmation Réseau IP en Java Classes et Interfaces : java.net javax.net (avec ssl ) adresse IPv4 : InetAddress socket TCP : Socket, ServerSocket socket UDP : DatagramSocket, DatagramPacket couche application : URL,URI, URLConnection,HttpURLConnection,... 14
2.s Classe InetAddress La classe InetAddress représente les adresses IPs v4 ou v6. Inet4Address Inet6Address 2.t Classe Inet4Address String gethostaddress() : retourne la représentation textuelle (pointée) d une adresse, static InetAddress getbyaddress(byte[] addr) : retourne un objet InetAddress correspondant à l adresse addr, static InetAddress getbyname(string host) : adresse IP après résolution du nom host, String gethostname() : nom de l hôte 2.u Classes Socket, ServerSocket Rappel : TCP/IP est orientée connexion. Une connexion est caractérisée par adresses et ports. ServerSocket est la classe des flux socket côté serveur (ie en attente de la connexion). Socket est la classe des flux socket côté client (ie initiateur de la connexion). Rq. Ces classes concernent IPv4 mais l implémentation peut être complètement surchargée... 2.v Classe ServerSocket ServerSocket(int port) : crée une socket écoutant sur le port port ServerSocket(int port, int backlog) : crée une socket écoutant sur le port port, avec une file d attente de taille backlog. ServerSocket(int port, int backlog, InetAddress bindaddr), idem, la socket n écoute que sur l interface correspondant à bindaddr. Socket accept() : attend une connexion entrante et renvoie une Socket lorsque celle-ci arrive public void setreuseaddress(boolean on) : active/désactive l option SO_REUSEADDR close() : fermer la socket. ces méthodes peuvent provoquer des SocketException ou des IOException 2.w Classe Socket Socket(InetAddress address, int port) se connecter à l adresse address et au port port, Socket(String host, int port) : se connecter à l hôte de nom host et au port port, 15
InetAddress getinetaddress() : renvoie l adresse à laquelle est connectée cette socket, int getport() : renvoie le port auquel est connectée cette socket, InputStream getinputstream() : renvoie le flux émis par l autre extrémité de la socket, OutputStream getoutputstream() : renvoie le flux permettant de communiquer vers l autre extrémité de la socket, close() : fermer la socket. 2.x Classe Socket (Exceptions) ces méthodes peuvent provoquer des SocketException ou des IOException Rq. Lectures et écritures se font de manière classique avec BufferedWriter, BufferedReader, par exemple. 2.y Classes DatagramSocket, PacketDatagram DatagramSocket() : crée une socket UDP sur le premier port disponible, DatagramSocket(int port) : crée une socket UDP sur le port port, void connect(inetaddress address, int port), se connecter à l adresse adresse et au port port, void send(datagrampacket p) : envoyer le datagramme p, void receive(datagrampacket p) : recevoir le datagramme p, void close() : fermer cette socket, byte[] getdata() : obtenir la charge utile du datagramme, byte[] setdata() : définir la charge utile du datagramme. 16