X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=network.tex;h=879f9708bda4d2ccc59f534e7806865604d9aaab;hp=fc54b79aadf6ef4b4a1159387c9ec67da4ae315f;hb=09473ed326013ece27d53cd5ff9f96064cbce9f3;hpb=09fff83335c84e1290f725341b0959344e5a7b03 diff --git a/network.tex b/network.tex index fc54b79..879f970 100644 --- a/network.tex +++ b/network.tex @@ -1,16 +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, per evitare un +capitolo puramente teorico 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 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, con un'ottica improntata a sottolineare +i concetti più importanti da conoscere ai fini della programmazione. \section{Il modello client-server} \label{sec:net_cliserv} @@ -35,18 +35,18 @@ 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. +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. \subsection{Un primo esempio di client} @@ -62,7 +62,7 @@ estensivamente pi 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. +restituisce l'ora locale della macchina a cui si effettua la richiesta. \begin{figure}[!htb] @@ -121,16 +121,16 @@ int main(int argc, char *argv[]) \label{fig:net_cli_code} \end{figure} -Il sorgente completo del programma (\texttt{SimpleDaytimeTCPClient.c}, che +Il sorgente completo del programma (\texttt{ElemDaytimeTCPClient.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. +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}). +\capref{sec:proc_opt_handling}). 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 @@ -151,7 +151,7 @@ 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 +server specificato dall'indirizzo immesso nella struttura passata 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 @@ -186,7 +186,7 @@ necessario deve provvedere il programma stesso. 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 +(\texttt{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file nella directory \texttt{sources}. \begin{figure}[!htbp] @@ -290,7 +290,7 @@ 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 +È importante 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 @@ -321,7 +321,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 @@ -350,17 +350,15 @@ 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 - - \caption{Struttura a livelli dei protocolli OSi e TCP/IP, con la - relative corrispondeze e la divisione fra kernel e user space.} + \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} @@ -369,7 +367,7 @@ Cos 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 @@ -384,11 +382,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 @@ -396,8 +393,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 @@ -414,41 +411,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. - - -\begin{figure}[!htbp] +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} -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. - -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} @@ -510,7 +506,7 @@ 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, -concentrandoci per le ragioni esposte sul livello di trasposto. All'interno di +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. @@ -518,12 +514,12 @@ nella maggior parte delle applicazioni. Benché si parli di TCP/IP questa famiglia di protocolli è composta anche da altri membri. In \nfig\ si è riportato uno schema che mostra un panorama sui -vari prottocolli della famiglia, e delle loro relazioni reciproche e con +vari protocolli della famiglia, e delle loro relazioni reciproche e con alcune dalle principali applicazioni che li usano. \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} @@ -533,7 +529,7 @@ 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 @@ -559,7 +555,7 @@ I vari protocolli mostrati in figura sono i seguenti: da ICMPv6. \item \textsl{ICMP} \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 @@ -624,7 +620,7 @@ grandi linee nei seguenti punti: \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 all'ampiamento degli 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 @@ -636,22 +632,22 @@ grandi linee nei seguenti punti: \end{itemize} Maggiori dettagli riguardo a caratteristiche, notazioni e funzionamento del -protocollo IP sono forniti nell'appendice \ref{cha:ip_protocol}. +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 @@ -673,7 +669,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. @@ -692,7 +688,7 @@ 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 @@ -729,7 +725,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 @@ -746,4 +742,107 @@ controllo di flusso e della gestione della sequenzialit effettuato per entrambe le direzioni di comunicazione. Una descrizione più accurata del protocollo è fornita in appendice -\ref{cha:tcp_protocol}. \ No newline at end of file +\capref{cha:tcp_protocol}. + +\subsection{Limiti e dimensioni riguardanti la trasmissione dei dati} +\label{sec:net_lim_dim} + +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} + +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}