X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=network.tex;h=de8376f830c29db41bae36c0b933a046d434bbca;hp=80d37ebad9a5bd76f3290f8f92c1969a16bd6618;hb=429f6e0da8fc282eb6611b6fe83fdf58ae8da611;hpb=60ea832813214f6bc4a9761a85d9d2b2038991aa diff --git a/network.tex b/network.tex index 80d37eb..de8376f 100644 --- a/network.tex +++ b/network.tex @@ -1,17 +1,16 @@ \chapter{Introduzione alla programmazione di rete} \label{cha:network} -In questo capitolo sarà fatta un'introduzione ai contetti generali che servono -come prerequisiti per capire la programmazione di rete, partiremo con due -semplici esempi per poi passare ad un esame a grandi linee dei protocolli di -rete e di come questi sono organizzati e interagiscono. +In questo capitolo sarà fatta un'introduzione ai concetti generali che servono +come prerequisiti per capire la programmazione di rete, non tratteremo quindi +aspetti specifici ma faremo una breve introduzione al modello più comune usato +nella programmazione di rete, per poi passare ad un esame a grandi linee dei +protocolli di rete e di come questi sono organizzati e interagiscono. In particolare, avendo assunto l'ottica di un'introduzione mirata alla -programmazione, ci concentreremo sul protocollo più diffuso, TCP/IP, che è -quello che sta alla base di internet, ed in particolare prenderemo in esame in -questa introduzione i concetti più importanti da conoscere ai fini della -programmazione. - +programmazione, ci concentreremo sul protocollo più diffuso, il TCP/IP, che è +quello che sta alla base di internet, avendo cura di sottolineare i concetti +più importanti da conoscere per la scrittura dei programmi. \section{Il modello client-server} \label{sec:net_cliserv} @@ -36,268 +35,20 @@ generale anche per programmi che non fanno necessariamente uso della rete, come il sistema a finestre. Normalmente si dividono i server in due categorie principali, e vengono detti -\textit{concorrenti} o \textit{iterativi}, sulla base del loro comportamento. +\textsl{concorrenti} o \textsl{iterativi}, sulla base del loro comportamento. -Un server iterativo risponde alla richiesta inviando i dati e resta occupato -(non rispondendo ad ulteriori richieste) fintanto che non ha concluso la -richiesta. Una volta completata la richiesta il server diventa di nuovo +Un \textsl{server iterativo} risponde alla richiesta inviando i dati e resta +occupato (non rispondendo ad ulteriori richieste) fintanto che non ha concluso +la richiesta. Una volta completata la richiesta il server diventa di nuovo disponibile. -Un server concorrente al momento di trattare la richiesta crea un processo -figlio incaricato di fornire i servizi richiesti, per poi porsi in attesa di -ulteriori richieste. In questo modo più richieste possono essere soddisfatte -contemporaneamente; una volta che il processo figlio ha concluso il suo lavoro -viene terminato, mentre il server originale resta sempre attivo. - - -\subsection{Un primo esempio di client} -\label{sec:net_cli_sample} - -Per evitare di rendere l'esposizione dei concetti generali sulla rete -puramente teorica iniziamo con il mostrare un semplice esempio di client TCP. -In \nfig\ è riportata la sezione principale del codice del nostro client -elementare per il servizio \textit{daytime}, un servizio standard che -restituisce l'ora locale della macchina a cui si effettua la richesta. - -\begin{figure}[!htbp] - \footnotesize - \begin{lstlisting}{} -#include /* predefined types */ -#include /* include unix standard library */ -#include /* IP addresses conversion utiliites */ -#include /* socket library */ -#include /* include standard I/O library */ - -int main(int argc, char *argv[]) -{ - int sock_fd; - int i, nread; - struct sockaddr_in serv_add; - char buffer[MAXLINE]; - ... - /* create socket */ - if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("Socket creation error"); - return -1; - } - /* initialize address */ - memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */ - serv_add.sin_family = AF_INET; /* address type is INET */ - serv_add.sin_port = htons(13); /* daytime post is 13 */ - /* build address using inet_pton */ - if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) { - perror("Address creation error"); - return -1; - } - /* extablish connection */ - if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { - perror("Connection error"); - return -1; - } - /* read daytime from server */ - while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) { - buffer[nread]=0; - if (fputs(buffer, stdout) == EOF) { /* write daytime */ - perror("fputs error"); - return -1; - } - } - /* error on read */ - if (nread < 0) { - perror("Read error"); - return -1; - } - /* normal exit */ - return 0; -} - \end{lstlisting} - \caption{Esempio di codice di un client elementare per il servizio daytime.} - \label{fig:net_cli_code} -\end{figure} - -Scopo di questo esempio è fornire un primo approccio alla programmazione di -rete, per questo motivo non ci dilungheremo nel trattare il significato dei -termini o il funzionamento delle varie funzioni utilizzate. Tutto questo sarà -esaminato in dettaglio nel seguito, per cui qui ci limiteremo a citarli senza -ulteriori spiegazioni. - -Il sorgente completo del programma (\texttt{SimpleDaytimeTCPClient.c}, che -comprende il trattamento delle opzioni e una funzione per stampare un -messaggio di aiuto) è allegato alla guida nella sezione dei codici sorgente e -può essere compilato su una qualunque macchina linux. - -Il programma anzitutto include gli header necessari (\texttt{\small 1--5}); -dopo la dichiarazione delle variabili (\texttt{\small 9--12}) si è omessa -tutta la parte relativa al trattamento degli argomenti passati dalla linea di -comando (effettuata con le apposite routines illustrate in -\ref{cha:parameter_options}). - -Il primo passo (\texttt{\small 14--18}) è creare un \textit{socket} IPv4 -(\texttt{AF\_INET}), di tipo TCP \texttt{SOCK\_STREAM} (in sostanza un canale -di comunicazione attraverso internet, questi termini verranno spiegati con -precisione più avanti). La funzione \texttt{socket} ritorna un descrittore, -analogo a quello dei file, che viene usato per identificare il socket in tutte -le chiamate successive. Nel caso la chiamata fallisca si stampa un errore con -la relativa routine e si esce. - -Il passo seguente (\texttt{\small 19--27}) è quello di costruire una apposita -struttura \texttt{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed -il numero della porta del servizio. Il primo passo è inizializzare tutto a -zero, per poi inserire il tipo di protocollo e la porta (usando per -quest'ultima la funzione \texttt{htons} per convertire il formato dell'intero -usato dal computer a quello usato nella rete), infine si utilizza la funzione -\texttt{inet\_pton} per convertire l'indirizzo numerico passato dalla linea di -comando. - -Usando la funzione \texttt{connect} sul socket creato in precedenza -(\texttt{\small 28--32}) si provvede poi a stabilire la connessione con il -server specificato dall'indirizzo immesso nella struttura possata come secondo -argomento, il terzo argomento è la dimensione di detta struttura. Dato che -esistono diversi tipi di socket, si è dovuto effettuare un cast della -struttura inizializzata in precedenza, che è specifica per i socket IPv4. Un -valore di ritorno negativo implica il fallimento della connessione. - -Completata con successo la connessione il passo successivo (\texttt{\small - 34--40}) è leggere la data dal socket; il server invierà sempre una stringa -di 26 caratteri della forma \verb|Wed Apr 4 00:53:00 2001\r\n|, che viene -letta dalla funzione \texttt{read} e scritta su \texttt{stdout}. - -Dato il funzionamento di TCP la risposta potrà tornare in un unico pacchetto -di 26 byte (come avverrà senz'altro nel caso in questione) ma potrebbe anche -arrivare in 26 pacchetti di un byte. Per questo nel caso generale non si può -mai assumere che tutti i dati arrivino con una singola lettura, pertanto -quest'ultima deve essere effettuata in un loop in cui si continui a leggere -fintanto che la funzione \texttt{read} non ritorni uno zero (che significa che -l'altro capo ha chiuso la connessione) o un numero minore di zero (che -significa un errore nella connessione). - -Si noti come in questo caso la fine dei dati sia specificata dal server che -chiude la connessione; questa è una delle tecniche possibili (è quella usata -pure dal protocollo HTTP), ma ce ne possono essere altre, ad esempio FTP marca -la conclusione di un blocco di dati con la sequenza ASCII \verb|\r\n| -(carriage return e line feed), mentre il DNS mette la lunghezza in testa ad -ogni blocco che trasmette. Il punto essenziale è che TCP non provvede nessuna -indicazione che permetta di marcare dei blocchi di dati, per cui se questo è -necessario deve provvedere il programma stesso. - -\subsection{Un primo esempio di server} -\label{sec:net_serv_sample} - -Dopo aver illustrato il client daremo anche un esempio di un server -elementare, in grado di rispondere al precedente client. Il listato è -nuovamente mostrato in \nfig, il sorgente completo -(\texttt{SimpleDaytimeTCPServer.c}) è allegato insieme agli altri file nella -directory \texttt{sources}. +Un \textsl{server concorrente} al momento di trattare la richiesta crea un +processo figlio incaricato di fornire i servizi richiesti, per poi porsi in +attesa di ulteriori richieste. In questo modo più richieste possono essere +soddisfatte contemporaneamente; una volta che il processo figlio ha concluso +il suo lavoro viene terminato, mentre il server originale resta sempre attivo. -\begin{figure}[!htbp] - \footnotesize - \begin{lstlisting}{} -#include /* predefined types */ -#include /* include unix standard library */ -#include /* IP addresses conversion utiliites */ -#include /* socket library */ -#include /* include standard I/O library */ -#include -#define MAXLINE 80 -#define BACKLOG 10 -int main(int argc, char *argv[]) -{ -/* - * Variables definition - */ - int list_fd, conn_fd; - int i; - struct sockaddr_in serv_add; - char buffer[MAXLINE]; - time_t timeval; - - ... - - /* create socket */ - if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("Socket creation error"); - exit(-1); - } - /* initialize address */ - memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */ - serv_add.sin_family = AF_INET; /* address type is INET */ - serv_add.sin_port = htons(13); /* daytime port is 13 */ - serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ - /* bind socket */ - if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) { - perror("bind error"); - exit(-1); - } - /* listen on socket */ - if (listen(list_fd, BACKLOG) < 0 ) { - perror("listen error"); - exit(-1); - } - /* write daytime to client */ - while (1) { - if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) { - perror("accept error"); - exit(-1); - } - timeval = time(NULL); - snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval)); - if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) { - perror("write error"); - exit(-1); - } - close(conn_fd); - } - /* normal exit */ - exit(0); -} - \end{lstlisting} - \caption{Esempio di codice di un semplice server per il servizio daytime.} - \label{fig:net_serv_code} -\end{figure} -Come per il client si includono gli header necessari a cui è aggiunto quello -per trattare i tempi, e si definiscono alcune costanti e le variabili -necessarie in seguito (\texttt{\small 1--18}), come nel caso precedente si -sono omesse le parti relative al trattamento delle opzioni da riga di comando. - -La creazione del socket (\texttt{\small 22--26}) è analoga al caso precedente, -come pure l'inizializzazione della struttura \texttt{sockaddr\_in}, anche in -questo caso si usa la porta standard del servizio daytime, ma come indirizzo -IP si il valore predefinito \texttt{INET\_ANY} che corrisponde ad un indirizzo -generico (\texttt{\small 27--31}). - -Si effettua poi (\texttt{\small 32--36}) la chiamata alla funzione -\texttt{bind} che permette di associare la precedente struttura al socket, in -modo che quest'ultimo possa essere usato per accettare connessioni su una -qualunque delle interfacce di rete locali. - -Il passo successivo (\texttt{\small 37--41}) è mettere ``in ascolto'' il -socket, questo viene effettuato con la funzione \texttt{listen} che dice al -kernel di accettare connessioni per il socket specificato, la funzione indica -inoltre, con il secondo parametro, il numero massimo di connessioni che il -kernel accetterà di mettere in coda per il suddetto socket. - -Questa ultima chiamata completa la preparazione del socket per l'ascolto (che -viene chiamato anche \textit{listening descriptor}) a questo punto il processo -è mandato in sleep (\texttt{\small 44--47}) con la successiva chiamata alla -funzione \texttt{accept}, fin quando non arriva e viene accettata una -connessione da un client. - -Quando questo avviene \texttt{accept} ritorna un secondo descrittore di -socket, che viene chiamato \textit{connected descriptor} che è quello che -viene usato dalla successiva chiamata alla \texttt{write} per scrivere la -risposta al client, una volta che si è opportunamente (\texttt{\small 48--49}) -costruita la stringa con la data da trasmettere. Completata la trasmissione il -nuovo socket viene chiuso (\texttt{\small 54}). -Il tutto è inserito in un loop infinito (\texttt{\small 42--55}) in modo da -poter ripetere l'invio della data ad una successiva connessione. - -È impostante notare che questo server è estremamente elementare, infatti a -parte il fatto di essere dipendente da IPv4, esso è in grado di servire solo -un client alla volta, è cioè un \textsl{server iterativo}, inoltre esso è -scritto per essere lanciato da linea di comando, se lo si volesse utilizzare -come demone di sistema (che è in esecuzione anche quando non c'è nessuna shell -attiva), occorrerebbero delle opportune modifiche. \section{I protocolli di rete} \label{sec:net_protocols} @@ -319,7 +70,7 @@ macchine diverse conversano tramite lo stesso protocollo. Questo modello di funzionamento è stato stato standardizzato dalla \textit{International Standards Organization} (ISO) che ha preparato fin dal 1984 il Modello di Riferimento \textit{Open Systems Interconnection} (OSI), strutturato in sette -livelli, secondo la tabella in \ntab. +livelli, secondo quanto riportato in \ntab. \begin{table}[htb] \centering @@ -348,15 +99,24 @@ quest'ultimo viene comunemente chiamato modello DoD (\textit{Department of Defense}), dato che fu sviluppato dall'agenzia ARPA per il Dipartimento della Difesa Americano. +\begin{figure}[!htbp] + \centering + \includegraphics[width=8cm]{img/iso_tcp_comp.eps} + \caption{Struttura a livelli dei protocolli OSI e TCP/IP, con la + relative corrispondenze e la divisione fra kernel e user space.} + \label{fig:net_osi_tcpip_comp} +\end{figure} + + \subsection{Il modello DoD (TCP/IP)} \label{sec:net_tcpip_overview} Così come ISO/OSI anche TCP/IP è stato strutturato in livelli (riassunti in -\ntab); un confronto fra i due è riportato in \nfig\ dove viene evidenziata +\ntab); un confronto fra i due è riportato in \curfig\ dove viene evidenziata anche la corrispondenza fra i rispettivi livelli (che comunque è approssimativa) e su come essi vanno ad inserirsi all'interno del sistema operativo rispetto alla divisione fra user space e kernel space spiegata in -\ref{sec:intro_unix_struct}. +\secref{sec:intro_unix_struct}. \begin{table}[htb] \centering @@ -371,11 +131,10 @@ operativo rispetto alla divisione fra user space e kernel space spiegata in device driver \& scheda di interfaccia \\ \hline \end{tabular} -\caption{I quattro livelli del protocollo TPC/IP.} +\caption{I quattro livelli del protocollo TCP/IP.} \label{tab:net_layers} \end{table} - Come si può notare TCP/IP è più semplice del modello ISO/OSI e strutturato in soli quattro livelli. Il suo nome deriva dai due principali protocolli che lo compongono, il TCP \textit{Trasmission Control Protocol} e l'IP @@ -383,8 +142,8 @@ compongono, il TCP \textit{Trasmission Control Protocol} e l'IP \begin{description} \item \textbf{Applicazione} É relativo ai programmi di interfaccia utente, in - genere questi vengono realizzati secondo il modello Client-Server (vedi - \ref{sec:net_cliserv}. + genere questi vengono realizzati secondo il modello client-server (vedi + \secref{sec:net_cliserv}. \item \textbf{Trasporto} Fornisce la comunicazione tra le due stazioni terminali su cui girano gli applicativi, regola il flusso delle informazioni, e può fornire un trasporto affidabile, cioè con recupero @@ -401,32 +160,40 @@ compongono, il TCP \textit{Trasmission Control Protocol} e l'IP \end{description} -La comunicazione fra due stazioni avviene pertanto secondo le modalità -illustrate in \nfig. - -Le singole applicazioni si scambieranno i dati secondo un loro formato -specifico, implementando un protocollo di applicazione (esempi possono essere -HTTP, POP, telnet, SMTP, etc). - -Questi dati vengono inviati al livello di trasporto usando un'interfaccia -opportuna (i \textit{socket}, che esamineremo in dettaglio in seguito), i -quali li spezzerà in pacchetti di dimensione opportuna e li incapsulerà -all'interno del suo protocollo di trasporto aggiungendo ad ogni pacchetto le -informazioni necessarie alla gestione di quest'ultimo. Questo processo viene -svolto dirattamente nel kernel ad esempio dallo stack TCP nel caso il -protocollo di trasporto sia questo. - -Una volta composto il pacchetto nel formato adatto al protocollo di trasporto -usato questo sarà passato al successivo livello, quello del collegamento che -si occupa di inserire le opportune informazioni per poter effettuare -l'instradamento nella rete ed il recapito alla destinazione finale. In genere -questo è il livello di IP (Internet Protocol), a cui vengono inseriti i numeri -IP che identificano i computer su internet. +La comunicazione fra due stazioni avviene secondo le modalità illustrate in +\nfig, dove si è riportato il flusso dei dati reali e i protocolli usati per +lo scambio di informazione su ciascuno livello. +\begin{figure}[!htb] + \centering + \includegraphics[width=6cm]{img/tcp_data_flux.eps} + \caption{Strutturazione del flusso dei dati nella comunicazione fra due + applicazioni attraverso i protocolli della suite TCP/IP.} + \label{fig:net_tcpip_data_flux} +\end{figure} -L'ultimo passo è il trasferimento del pacchetto al driver della interfaccia di -trasmissione che si incarica di incapsularlo nel relativo protocollo di -trasmissione fisica usato dall'hardware usato per la comunicazione (ad esempio -ethernet per una scheda di rete). +La struttura della comuniczione pertanto si può riassumere nei seguenti passi: +\begin{itemize} +\item Le singole applicazioni si scambieranno i dati secondo un loro formato + specifico, implementando un protocollo di applicazione (esempi possono + essere HTTP, POP, telnet, SMTP, etc). +\item Questi dati vengono inviati al livello di trasporto usando + un'interfaccia opportuna (i \textit{socket}, che esamineremo in dettaglio in + seguito). Qui verranno spezzati in pacchetti di dimensione opportuna e + incapsulati nel protocollo di trasporto, aggiungendo ad ogni pacchetto le + informazioni necessarie per la sua gestione. Questo processo viene + svolto direttamente nel kernel ad esempio dallo stack TCP nel caso il + protocollo di trasporto sia questo. +\item Una volta composto il pacchetto nel formato adatto al protocollo di + trasporto usato questo sarà passato al successivo livello, quello del + collegamento che si occupa di inserire le opportune informazioni per poter + effettuare l'instradamento nella rete ed il recapito alla destinazione + finale. In genere questo è il livello di IP (Internet Protocol), a cui + vengono inseriti i numeri IP che identificano i computer su internet. +\item L'ultimo passo è il trasferimento del pacchetto al driver della + interfaccia di trasmissione che si incarica di incapsularlo nel relativo + protocollo di trasmissione fisica usato dall'hardware usato per la + comunicazione (ad esempio ethernet per una scheda di rete). +\end{itemize} \subsection{Criteri generali del design di TCP/IP} @@ -466,39 +233,52 @@ trattato uniformemente da tutti i nodi della rete. \section{Il protocollo TCP/IP} \label{sec:net_tpcip} -Come già affermato il protocollo TCP/IP è un insieme di protocolli diversi, +Come appena mostrato il protocollo TCP/IP è un insieme di protocolli diversi, che operano su 4 livelli diversi. Per gli interessi della programmazione di rete però sono importanti principalmente i due livelli centrali, e soprattutto -quello di trasporto, su cui è innestata l'interfaccia fra kernel space e user -space. - -Il livello 4 infatti è normalmente gestito dal kernel, e si accede ad esso -solo quando si vogliono fare applicazioni di sistema per il controllo della -rete (locale) a basso livello, un uso quindi molto specialistico. Il livello 1 -invece dipende dalle singole applicazioni ed è di nuovo troppo specifico per -essere affrontato qui. +quello di trasporto. + +La principale interfaccia di programmazione di rete, quella dei socket, è +infatti un'interfaccia nei confronti di quest'ultimo. Questo avviene perché al +di sopra del livello di trasporto i programmi hanno a che fare solo con +dettagli specifici delle applicazioni, mentre al di sotto vengono curati tutti +i dettagli relativi alla comunicazione. È pertanto naturale definire una API +su questo confine tanto più che è proprio li (come evidenziato in \pfig) che +nei sistemi unix (e non solo) viene inserita la divisione fra kernel space e +user space. + +In realtà in un sistema unix è possibile accedere anche agli altri livelli +inferiori (e non solo a quello di trasporto) con opportune interfacce (la cosa +è indicata in \pfig\ lasciando uno spazio fra UDP e TCP), ma queste vengono +usate solo quando si vogliono fare applicazioni di sistema per il controllo +della rete a basso livello, un uso quindi molto specialistico, e che non +rientra in quanto trattato qui. In questa sezione daremo una breve descrizione dei vari protocolli di TCP/IP, -ma ci concentreremo principalmente sul livello di trasposto e in particolare -sul protocollo TCP sia per il ruolo centrale che esso svolge nella maggior -parte delle applciazioni, sia per la sua complessità che necessita di maggiori -spiegazioni. +concentrandoci per le ragioni esposte sul livello di trasporto. All'interno di +questo privilegeremo poi il protocollo TCP, per il ruolo centrale che svolge +nella maggior parte delle applicazioni. \subsection{Il quadro generale} Benché si parli di TCP/IP questa famiglia di protocolli è composta anche da -altri membri. In \nfig\ si è riportato una figura di quadro che mostra un -panorama sull'intera famiglia, e di come i vari protocolli vengano usati dalle -applicazioni. +altri membri. In \nfig\ si è riportato uno schema che mostra un panorama sui +vari protocolli della famiglia, e delle loro relazioni reciproche e con +alcune dalle principali applicazioni che li usano. -La figura è da fare ... +\begin{figure}[!htbp] + \centering + \includegraphics[width=10cm]{img/tcpip_overview.eps} + \caption{Panoramica sui vari protocolli che compongono la suite TCP/IP.} + \label{fig:net_tcpip_overview} +\end{figure} I vari protocolli mostrati in figura sono i seguenti: \begin{list}{}{} \item \textsl{IPv4} \textit{Internet Protocol version 4}. È quello che comunemente si chiama IP. Ha origine negli anni '80 e da allora è la base su - cui è cotriuta internet. Usa indirizzi a 32 bit e provvede la trasmissione + cui è costruita internet. Usa indirizzi a 32 bit e provvede la trasmissione dei pacchetti TCP, UDP, ICMP e IGMP. \item \textsl{IPv6} \textit{Internet Protocol version 6}. È stato progettato a metà degli anni '90 per rimpiazzare IPv4. Ha indirizzi a 128 bit e effettua @@ -507,9 +287,9 @@ I vari protocolli mostrati in figura sono i seguenti: orientato alla connessione che provvede un trasporto affidabile e bidirezionale di un flusso di dati. I socket TCP sono esempi di \textit{stream socket}. Il protocollo ha cura di tutti gli aspetti del - trasporto, come l'acknoweledgment, i timout, la ritrasmissione, etc. È usato - dalla maggior parte delle applicazioni. Può essere usato sia con IPv4 che - con IPv6. + trasporto, come l'acknoweledgment, i timeout, la ritrasmissione, etc. È + usato dalla maggior parte delle applicazioni. Può essere usato sia con IPv4 + che con IPv6. \item \textsl{UDP} \textit{User Datagram Protocol}. È un protocollo senza connessione a pacchetti. I socket UDP sono esempi di \textit{datagram socket}. Contrariamente al TCP in protocollo non è affidabile e non c'è @@ -517,13 +297,14 @@ I vari protocolli mostrati in figura sono i seguenti: ordine di arrivo. Può essere usato sia con IPv4 che con IPv6. \item \textsl{ICMP} \textit{Internet Control Message Protocol}. Gestisce gli errori e trasporta l'informazione di controllo fra stazioni remote e - instradatori (\textit{router} e \textit{host}). I messaggi sono normalmente + instradatori (\textit{host} e \textit{router}). I messaggi sono normalmente generati dal software del kernel che gestisce la comunicazione TCP/IP, anche - se può venire usato direttamente da alcuni programmi come \texttt{ping}. A - volte ci si riferisce ad esso come ICPMv4 per distinguerlo da ICMPv6. -\item \textsl{ICMP} \textit{Internet Group Management Protocol}. É un + se ICMP può venire usato direttamente da alcuni programmi come + \texttt{ping}. A volte ci si riferisce ad esso come ICPMv4 per distinguerlo + da ICMPv6. +\item \textsl{IGMP} \textit{Internet Group Management Protocol}. É un protocollo usato per il \textit{multicasting} (vedi - \ref{sec:xxx_multicast}), che è opzionale in IPv4. + \secref{sec:xxx_multicast}), che è opzionale in IPv4. \item \textsl{ARP} \textit{Address Resolution Protocol}. È il protocollo che mappa un indirizzo IP in un indirizzo hardware (come un indirizzo internet). È usato in reti di tipo broadcast come ethernet, token ring o @@ -552,7 +333,7 @@ Quando si parla di IP ci si riferisce in genere alla versione attualmente in uso che è la versione 4 (e viene pertanto chiamato IPv4). Questa versione venne standardizzata nel 1981 dall'RFC~719. -Internet protocol nasce per disaccoppiare le applicazioni della struttura +Internet Protocol nasce per disaccoppiare le applicazioni della struttura hardware delle reti di trasmissione, e creare una interfaccia di trasmissione dei dati indipendente dal sottostante substrato di rete, che può essere realizzato con le tecnologie più disparate (Ethernet, Token Ring, FDDI, etc.). @@ -584,38 +365,38 @@ grandi linee nei seguenti punti: supportare una gerarchia con più livelli di indirizzamento, un numero di nodi indirizzabili molto maggiore e una autoconfigurazione degli indirizzi \item l'introduzione un nuovo tipo di indirizzamento, l'\textit{anycast} che - si aggiungono agli usuali \textit{unycast} e \textit{multicast} + si aggiunge agli usuali \textit{unycast} e \textit{multicast} \item la semplificazione del formato della testata, eliminando o rendendo opzionali alcuni dei campi di IPv4, per eliminare la necessità di riprocessamento della stessa da parte dei router e contenere l'aumento di - dimensione dovuto ai nuovi indirizzi + dimensione dovuto all'ampliamento degli indirizzi \item un supporto per le opzioni migliorato, per garantire una trasmissione più efficiente del traffico normale, limiti meno stringenti sulle dimensioni delle opzioni, e la flessibilità necessaria per introdurne di nuove in futuro -\item il supporto per delle capacità di qualità di servizio (QoS) che permetta - di identificare gruppi di dati per i quali si può provvedere un trattamento - speciale (in vista dell'uso di internet per applicazioni multimediali e/o - ``real-time'') +\item il supporto per delle capacità di qualità di servizio (QoS) che + permettano di identificare gruppi di dati per i quali si può provvedere un + trattamento speciale (in vista dell'uso di internet per applicazioni + multimediali e/o ``real-time'') \end{itemize} -Per maggiori dettagli riguardo al protocollo si può consultare -\ref{sec:appA_ip}. +Maggiori dettagli riguardo a caratteristiche, notazioni e funzionamento del +protocollo IP sono forniti nell'appendice \capref{cha:ip_protocol}. \subsection{UDP: User Datagram Protocol)} \label{sec:net_udp} -UDP è un protocollo di trasporto molto semplice, la sua descizione completa è -contenuta dell'RFC~768, ma in sostanza esso è una semplice interfaccia a IP dal -livello di trasporto. Quando un'applicazione usa UDP essa scrive un pacchetto -di dati (il cosiddetto \textit{datagram} che da il nome al protocollo) su un -socket, al pacchetto viene aggiunto un header molto semplice (per una -descrizione più accurata vedi \ref{sec:appA_udp}), e poi viene passato al -livello superiore (IPv4 o IPv6 che sia) che lo spedisce verso la destinazione. -Dato che né IPv4 né IPv6 garantiscono l'affidabilità niente assicura che il -pacchetto arrivi a destinazione, né che più pacchetti arrivino nello stesso -ordine in cui sono stati spediti. +UDP è un protocollo di trasporto molto semplice, la sua descrizione completa è +contenuta dell'RFC~768, ma in sostanza esso è una semplice interfaccia a IP +dal livello di trasporto. Quando un'applicazione usa UDP essa scrive un +pacchetto di dati (il cosiddetto \textit{datagram} che da il nome al +protocollo) su un socket, al pacchetto viene aggiunto un header molto semplice +(per una descrizione più accurata vedi \secref{sec:xxx_udp}), e poi viene +passato al livello superiore (IPv4 o IPv6 che sia) che lo spedisce verso la +destinazione. Dato che né IPv4 né IPv6 garantiscono l'affidabilità niente +assicura che il pacchetto arrivi a destinazione, né che più pacchetti arrivino +nello stesso ordine in cui sono stati spediti. Pertanto il problema principale che si affronta quando si usa UDP è la mancanza di affidabilità, se si vuole essere sicuri che i pacchetti arrivino a @@ -637,7 +418,7 @@ Infine UDP (\textit{connectionless}) in quanto non è necessario stabilire nessun tipo di relazione tra origine e destinazione dei pacchetti. Si hanno così situazioni in cui un client può scrivere su uno stesso socket pacchetti destinati a -server diversi, o un server ricevere su un socket paccetti provenienti da +server diversi, o un server ricevere su un socket pacchetti provenienti da client diversi. Il modo più semplice di immaginarsi il funzionamento di UDP è quello della radio, in cui si può ``trasmettere a'' e ``ricevere da'' più stazioni usando la stessa frequenza. @@ -646,7 +427,7 @@ Nonostante gli evidenti svantaggi comportati dall'inaffidabilit grande pregio della velocità che in certi casi è essenziale; inoltre si presta bene per le applicazioni in cui la connessione non è necessaria e costituirebbe solo un peso di prestazioni mentre una perdita di pacchetti può -essere tollerata, come quelle che usano il multicasting. +essere tollerata, ad esempio quelle che usano il multicasting. \subsection{TCP: Transport Control Protocol)} \label{sec:net_tcp} @@ -656,19 +437,20 @@ diverso da UDP; alla base del suo design infatti non stanno semplicit velocità, ma la ricerca della massima affidabilità possibile nella trasmissione dei dati. -La prima differenza con UDP è che TCP provvede sempre una conessione diretta +La prima differenza con UDP è che TCP provvede sempre una connessione diretta fra un client e un server, attraverso la quale essi possono comunicare; per questo il paragone più appropriato per questo protocollo è quello del collegamento telefonico, in quanto prima viene stabilita una connessione fra -due stazioni su cui poi viene effettuata una comunicazione diretta. +due i due capi della comunicazione su cui poi viene quest'ultima viene +effettuata. Caratteristica fondamentale di TCP è l'affidabilità; quando i dati vengono inviati attraverso una connessione ne viene richiesto un ``ricevuto'' (il cosiddetto \textit{acknowlegment}), se questo non arriva essi verranno -ritrasmessi facendo un determinato numero di tentativi intervallati da un -periodo di tempo crescente, fintanto che la connessione sarà considerata -fallita o caduta la connessione (con un errore di \textit{time-out}), dopo un -periodo di tempo che dipende dall'implementazione e che può variare far i +ritrasmessi per un determinato numero di tentativi, intervallati da un +periodo di tempo crescente, fino a che sarà considerata fallita o caduta la +connessione (e generato un errore di \textit{time-out}), dopo un periodo di +tempo che dipende dall'implementazione e che può variare far i quattro e i dieci minuti. Inoltre per tenere conto delle diverse condizioni in cui può trovarsi la linea @@ -692,7 +474,7 @@ Il protocollo provvede anche un controllo di flusso (\textit{flow control}), cioè specifica sempre all'altro capo della trasmissione quanti dati può ricevere tramite una \textit{advertised window} (letteralmente finestra annunciata), che indica lo spazio disponibile nel buffer di ricezione, -cosicchè nella trasmissione non vengano inviati più dati di quelli che possono +cosicché nella trasmissione non vengano inviati più dati di quelli che possono essere ricevuti. Questa finestra cambia dinamicamente diminuendo con la ricezione dei dati dal @@ -708,18 +490,108 @@ stesso tempo, il che poi comporta che quanto dicevamo a proposito del controllo di flusso e della gestione della sequenzialità dei dati viene effettuato per entrambe le direzioni di comunicazione. +Una descrizione più accurata del protocollo è fornita in appendice +\capref{cha:tcp_protocol}. +\subsection{Limiti e dimensioni riguardanti la trasmissione dei dati} +\label{sec:net_lim_dim} -\subsection{Creazione e terminazione della connessione TCP} - -Per capire il funzionamento delle funzioni della interfaccia dei socket che -operano con TCP (come \texttt{connect}, \texttt{accept} e \texttt{close} che -vedremo più avanti) è fodamentale capire come funziona la creazione e la -conclusione di una connessione TCP. - - +Un aspetto di cui bisogna tenere conto, e che ritornerà in seguito, è che ci +sono una serie di limiti a cui la trasmissione dei dati attraverso i vari +livelli del protocollo deve sottostare, limiti che è opportuno tenere presente +perché in certi casi si possono avere delle conseguenze sul comportamento +delle applicazioni. +Un elenco di questi limiti è il seguente, insieme ad un breve accenno alle +loro origini ed alle eventuali implicazioni che possono avere: +\begin{itemize} +\item La dimensione massima di un pacchetti IP è di 65535 bytes, compreso + l'header. Questo è dovuto al fatto che la dimensione è indicata da un campo + apposito nell'header di IP che è lungo 16 bit (vedi + \tabref{tab:IP_ipv4head}). +\item La dimensione massima di un pacchetto normale di IPv6 è di 65575 bytes, + il campo apposito nell'header infatti è sempre a 16 bit, ma la dimensione + dell'header è fissa e di 40 byte e non è compresa nel valore indicato dal + suddetto campo. Inoltre IPv6 ha la possibilità di estendere la dimensione di + un pacchetto usando la \textit{jumbo payload option}. +\item Molte reti fisiche hanno un MTU (\textit{maximum tranfer unit}) che + dipende dal protocollo specifico usato al livello di link. Il più comune è + quello dell'ethernet che è pari a 1500 bytes, una serie di valori possibili + sono riportati in \ntab. +\end{itemize} -\subsection{Le porte} +Quando un pacchetto IP viene inviato su una interfaccia di rete e le sue +dimensioni eccedono la MTU viene eseguita la cosiddetta +\textit{frammentazione}, i pacchetti cioè vengono spezzati (sia da IPv4 che da +IPv6, anche se i pacchetti frammentati sono gestiti con modalità +diverse\footnote{il primo usa un flag nell'header, il secondo una opportuna + opzione, si veda \secref{cha:ip_protocol}}), in blocchi più piccoli che +possono essere trasmessi attraverso l'interfaccia. +\begin{table}[!htb] + \centering + \begin{tabular}[c]{|l|c|} + \hline + \textbf{Rete} & \textbf{MTU} \\ + \hline + \hline + Hyperlink & 65535 \\ + Token Ring IBM (16 Mbit/sec) & 17914 \\ + Token Ring IEEE 802.5 (4 Mbit/sec) & 4464 \\ + FDDI & 4532 \\ + Ethernet & 1500 \\ + X.25 & 576 \\ + \hline + \end{tabular} + \caption{Valori della MTU (\textit{maximum tranfer unit}) per una serie di + reti diverse.} + \label{tab:net_mtu_values} +\end{table} +La MTU più piccola fra due stazioni viene in genere chiamata \textit{path + MTU}, che dice qual'è la lunghezza massima oltre la quale un pacchetto +inviato da una stazione ad un'altra verrebbe senz'altro frammentato. Si tenga +conto che non è affatto detto che la \textit{path MTU} sia la stessa in +entrambe le direzioni, perché l'instradamento può essere diverso nei due +sensi, con diverse tipologie di rete coinvolte. + +Una delle differenze fra IPv4 e IPv6 é che per IPv6 la frammentazione può +essere eseguita solo alla sorgente, questo vuol dire che i router IPv6 non +frammentano i pacchetti che trasmettono (anche se possono frammentare i +pacchetti che generano loro stessi), mentre i router IPv4 si. In ogni caso una +volta frammentati i pacchetti possono essere riassemblati solo alla +destinazione. + +Nell'header di IPv4 è previsto il flag \texttt{DF} che specifica che il +pacchetto non deve essere frammentato; un router che riceva un pacchetto le +cui dimensioni eccedano quelle dell'MTU della rete di destinazione genererà un +messaggio di errore ICMPv4 di tipo \textit{destination unreachable, + fragentation needed but DF bit set}. + +Dato che i router IPv6 non possono effettuare la frammentazione la ricezione +di un pacchetto di dimensione eccessiva per la ritrasmissione genererà sempre +un messaggio di errore ICMPv6 di tipo \textit{packet too big}. + +Dato che il meccanismo di frammentazione e riassemblaggio comporta +inefficienza normalmente viene utilizzato il procedimento della \textit{path + MTU discover} (vedi RFC~1191 per IPv4 e RFC~1981 per IPv6) che permette di +trovare il \textit{path MTU} fra due stazioni; per la realizzazione del +procedimento si usa il flag DF di IPv4 e il comportamento normale di IPv6 +inviando delle opportune serie di pacchetti (per i dettagli vedere l'RFC~1191 +per IPv4 e l'RFC~1981 per IPv6) fintanto che non si hanno più errori. + +Il TCP usa sempre questo meccanismo, che per le implementazioni di IPv4 è +opzionale, mentre diventa obbligatorio per IPv6. Per IPv6 infatti, non +potendo i router frammentare i pacchetti, è necessario, per poter comunicare, +conoscere il \textit{path MTU}. + + +Infine TCP definisce una \textit{maximum segment size} MSS che annuncia +all'altro capo la dimensione massima del segmento di dati. + + +\subsection{Il passaggio dei dati in TCP} +\label{sec:net_tcp_pass} + +\subsection{Il passaggio dei dati in UDP} +\label{sec:net_udp_pass}