In questo capitolo inizieremo ad approndire la conoscenza dei socket TCP,
tratteremo qui dunque il funzionamento delle varie funzioni che si sono usate
-nei due esempi elementari forniti in precedenza (vedi \ref{sec:net_cli_sample}
-e \ref{sec:net_serv_sample}), previa una descrizione delle principali
-caratteristiche del funzionamento di una connessione TCP.
+nei due esempi elementari forniti in precedenza (vedi
+\secref{sec:net_cli_sample} e \secref{sec:net_serv_sample}), previa una
+descrizione delle principali caratteristiche del funzionamento di una
+connessione TCP.
La seconda parte del capitolo sarà poi dedicata alla scrittura di una prima
semplice applicazione client/server completa, che implementi il servizio
Il processo che porta a creare una connessione TCP è chiamato \textit{three
way handushake}; la successione tipica degli eventi (la stessa che si
verifica utilizzando il codice dei due precedenti esempi elementari
-\ref{fig:net_cli_code} e \ref{fig:net_serv_code}) che porta alla creazione di
-una connessione è la seguente:
+\figref{fig:net_cli_code} e \figref{fig:net_serv_code}) che porta alla
+creazione di una connessione è la seguente:
\begin{itemize}
\item Il server deve essere preparato per accettare le connessioni in arrivo;
\texttt{SYN}, \texttt{ACK}, \texttt{URG}, \texttt{FIN}, alcuni di essi,
come \texttt{SYN} (che sta per \textit{sincronize}) corrispondono a
funzioni particolari del protocollo e danno il nome al segmento, (per
- maggiori dettagli vedere \ref{cha:tcp_protocol})}, in sostanza viene
+ maggiori dettagli vedere \capref{cha:tcp_protocol})}, in sostanza viene
inviato al server un pacchetto IP che contiene solo gli header IP e TCP (con
il numero di sequenza iniziale e il flag \texttt{SYN}) e le opzioni di TCP.
connesione corrente. È possibile leggere e scrivere questo valore attraverso
l'opzione del socket \texttt{TCP\_MAXSEG}.
-\item \textit{window scale option} come spiegato in \ref{cha:tcp_protocol} il
+\item \textit{window scale option} come spiegato in \capref{cha:tcp_protocol} il
protocollo TCP implementa il controllo di flusso attraverso una
\textsl{finestra annunciata} (\textit{advertized window}) con la quale
ciascun capo della comunicazione dichiara quanto spazio disponibile ha in
Mentre per creare una connessione occorre un interscambio di tre segmenti, la
procedura di chiusura ne richede quattro; ancora una volta si può fare
-riferimento al codice degli esempi \ref{fig:net_cli_code} e
-\ref{fig:net_serv_code}, in questo caso la successione degli eventi è la
+riferimento al codice degli esempi \figref{fig:net_cli_code} e
+\figref{fig:net_serv_code}, in questo caso la successione degli eventi è la
seguente:
\begin{enumerate}
La emissione del FIN avviene quando il socket viene chiuso, questo però non
avviene solo per la chiamata della funzione \texttt{close} (come in
-\ref{fig:net_serv_code}), ma anche alla terminazione di un processo (come in
-\ref{fig:net_cli_code}). Questo vuol dire ad esempio che se un processo viene
-terminato da un segnale tutte le connessioni aperte verranno chiuse.
+\figref{fig:net_serv_code}), ma anche alla terminazione di un processo (come
+in \figref{fig:net_cli_code}). Questo vuol dire ad esempio che se un processo
+viene terminato da un segnale tutte le connessioni aperte verranno chiuse.
Infine è da sottolineare che, benché nella figura (e nell'esempio che vedremo
-in \ref{sec:TCPel_echo_example}) sia il client ad eseguire la chiusura attiva,
-nella realtà questa può essere eseguita da uno qualunque dei due capi della
-comunicazione (come in fatto in precedenza da \ref{fig:net_serv_code}), e
-benché quello del client sia il caso più comune ci sono alcuni servizi, il
-principale dei quali è l'HTTP, per i quali è il server ad effettuare la
-chiusura attiva.
+in \secref{sec:TCPel_echo_example}) sia il client ad eseguire la chiusura
+attiva, nella realtà questa può essere eseguita da uno qualunque dei due capi
+della comunicazione (come in fatto in precedenza da
+\figref{fig:net_serv_code}), e benché quello del client sia il caso più comune
+ci sono alcuni servizi, il principale dei quali è l'HTTP, per i quali è il
+server ad effettuare la chiusura attiva.
\subsection{Un esempio di connessione}
\label{sec:TCPel_conn_dia}
Una descrizione completa del funzionamento del protocollo va al di là degli
obiettivi di questo libro; un approfondimento sugli aspetti principali si
-trova in \ref{cha:tcp_protocol}, ma per una trattazione esauriente il miglior
+trova in \capref{cha:tcp_protocol}, ma per una trattazione esauriente il miglior
riferimento resta (FIXME citare lo Stevens); qui ci limiteremo a descrivere
brevemente un semplice esempio di connessione e le transizioni che avvengono
nei due casi appena citati (creazione e terminazione della connessione).
risposta.
Infine si ha lo scambio dei quattro segmenti che terminano la connessione
-secondo quanto visto in \ref{sec:TCPel_conn_term}; si noti che il capo della
+secondo quanto visto in \secref{sec:TCPel_conn_term}; si noti che il capo della
connessione che esegue la chiusura attiva entra nello stato
\textsl{TIME\_WAIT} su cui torneremo fra poco.
sulla rete; questo tempo è limitato perché ogni pacchetto IP può essere
ritrasmesso dai router un numero massimo di volte (detto \textit{hop limit}).
Il numero di ritrasmissioni consentito è indicato dal campo TTL dell'header di
-IP (per maggiori dettagli vedi \ref{sec:appA_xxx}), e viene decrementato ad
+IP (per maggiori dettagli vedi \secref{sec:appA_xxx}), e viene decrementato ad
ogni passaggio da un router; quando si annulla il pacchetto viene scartato.
Siccome il numero è ad 8 bit il numero massimo di ``salti'' è di 255, pertanto
anche se il TTL (da \textit{time to live}) non è propriamente un limite sul
usare sia UDP che TCP, e ci devono poter essere più connessioni in
contemporanea. Per poter tenere distinte le diverse connessioni entrambi i
protocolli usano i \textsl{numeri di porta}, che fanno parte, come si può
-vedere in \ref{sec:sock_sa_ipv4} e \ref{sec:sock_sa_ipv6} pure delle strutture
+vedere in \secref{sec:sock_sa_ipv4} e \secref{sec:sock_sa_ipv6} pure delle strutture
degli indirizzi del socket.
Quando un client contatta un server deve poter identificare con quale dei vari
Per capire meglio l'uso delle porte e come vengono utilizzate quando si ha a
che fare con un'applicazione client/server (come quella che scriveremo in
-\ref{sec:TCPel_echo_example}) esaminaremo cosa accade con le connessioni nel
+\secref{sec:TCPel_echo_example}) esaminaremo cosa accade con le connessioni nel
caso di un server TCP che deve gestire connessioni multiple.
Se esguiamo un \texttt{netstat} su una macchina di prova (che supponiamo avere
In questa sezione descriveremo in dettaglio le varie funzioni necessarie per
l'uso dei socket TCP già citate in precedenza (e utilizzate nei due esempi
-\ref{sec:net_cli_sample} e \ref{sec:net_serv_sample}) con l'eccezione della
-funzione \texttt{socket} che è già stata esaminata in dettaglio in
-\ref{sec:sock_socket}.
+\secref{sec:net_cli_sample} e \secref{sec:net_serv_sample}) con l'eccezione
+della funzione \texttt{socket} che è già stata esaminata in dettaglio in
+\secref{sec:sock_socket}.
In \nfig\ abbiamo un tipico schema di funzionamento di un'applicazione
client-server che usa i socket TCP: prima il server viene avviato ed in
seguito il client si connette, in questo caso, a differenza di quanto accadeva
-con gli esempi elementari del Cap.~\ref{cha:network} si assume che sia il
+con gli esempi elementari del Cap.~\capref{cha:network} si assume che sia il
client ad effettuare delle richieste a cui il server risponde, il client
notifica poi di avere concluso inviando un end-of-file a cui il server
risponderà anche lui chiudendo la connessione per aspettarne una nuova.
\end{figure}
Useremo questo schema per l'esempio di implementazione del servizio
-\texttt{echo} che illustreremo in \ref{sec:TCPel_echo_example}.
+\texttt{echo} che illustreremo in \secref{sec:TCPel_echo_example}.
\subsection{La funzione \texttt{bind}}
Il primo argomento è un file descriptor ottenuto da una precedente chiamata
a \texttt{socket}, mentre il secondo e terzo argomento sono rispettivamente
l'indirizzo (locale) del socket e la dimensione della struttura che lo
- contiene, secondo quanto già trattato in \ref{sec:sock_sockaddr}.
+ contiene, secondo quanto già trattato in \secref{sec:sock_sockaddr}.
La funzione restituisce zero in caso di successo e -1 per un errore, in caso
di errore. La variabile \texttt{errno} viene settata secondo i seguenti
Per specificare un indirizzo generico con IPv4 si usa il valore
\texttt{INADDR\_ANY}, il cui valore, come visto anche negli esempi precedenti
-è pari a zero, nell'esempio \ref{fig:net_serv_sample} si è usata
+è pari a zero, nell'esempio \figref{fig:net_serv_sample} si è usata
un'assegnazione immediata del tipo:
\begin{verbatim}
serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */
Il primo argomento è un file descriptor ottenuto da una precedente chiamata
a \texttt{socket}, mentre il secondo e terzo argomento sono rispettivamente
l'indirizzo e la dimensione della struttura che contiene l'indirizzo del
- socket, già descritta in \ref{sec:sock_sockaddr}.
+ socket, già descritta in \secref{sec:sock_sockaddr}.
La funzione restituisce zero in caso di successo e -1 per un errore, in caso
di errore. La variabile \texttt{errno} viene settata secondo i seguenti
La struttura dell'indirizzo deve essere inizializzata con l'indirizzo IP e il
numero di porta del server a cui ci si vuole connettere, come mostrato
-nell'esempio \ref{sec:net_cli_sample} usando le funzioni illustrate in
-\ref{sec:sock_addr_func}.
+nell'esempio \secref{sec:net_cli_sample} usando le funzioni illustrate in
+\secref{sec:sock_addr_func}.
Nel caso di socket TCP la funzione \texttt{connect} avvia il three way
handshake, e ritorna solo quando la connessione è stabilita o si è verificato
\end{enumerate}
Se si fa riferimento al diagramma degli stati del TCP riportato in
-\ref{fig:appB:tcp_state_diag} la funzione \texttt{connect} porta un socket
+\figref{fig:appB:tcp_state_diag} la funzione \texttt{connect} porta un socket
dallo stato \texttt{CLOSED} (lo stato iniziale in cui si trova un socket
appena creato) prima allo stato \texttt{SYN\_SENT} e poi, al ricevimento del
ACK, nello stato \texttt{ESTABLISHED}. Se invece la connessione fallisce il
\label{sec:filedir_org}
L'organizzazione dei nomi dei file deriva direttamente dall'organizzazione dei
-medesimi nell'albero descritto brevemente in \ref{sec:fileintr_overview}; una
-directory comunque, come già specificato in \ref{sec:fileintr_vfs}, è solo un
-particolare tipo di file che contiene le informazioni che associano un nome al
-contenuto. Per questo, anche se è usuale parlare di ``file in una directory''
-in realtà una directory contiene solo delle etichette per fare riferimento ai
-file stessi.
+medesimi nell'albero descritto brevemente in \secref{sec:fileintr_overview};
+una directory comunque, come già specificato in \secref{sec:fileintr_vfs}, è
+solo un particolare tipo di file che contiene le informazioni che associano un
+nome al contenuto. Per questo, anche se è usuale parlare di ``file in una
+directory'' in realtà una directory contiene solo delle etichette per fare
+riferimento ai file stessi.
I manuale delle librerie del C chiama i nomi contenuti nelle directory
\textsl{componenti} (in inglese \textit{file name components}), noi li
Se il pathname comincia per \texttt{/} la ricerca parte dalla directory radice
del processo; questa, a meno di un \textit{chroot} (su cui torneremo in
-seguito, vedi \ref{sec:proc_chroot}) è la stessa per tutti i processi ed
+seguito, vedi \secref{sec:proc_chroot}) è la stessa per tutti i processi ed
equivale alla directory radice dell'albero (come descritto in
-\ref{sec:fileintr_overview}): in questo caso si parla di un pathname
+\secref{sec:fileintr_overview}): in questo caso si parla di un pathname
\textsl{assoluto}. Altrimenti la ricerca parte dalla directory corrente (su
-cui torneremo più avanti in \ref{sec:filedir_work_dir}) ed il pathname è detto
-\textsl{relativo}.
+cui torneremo più avanti in \secref{sec:filedir_work_dir}) ed il pathname è
+detto \textsl{relativo}.
I nomi \texttt{.} e \texttt{..} hanno un significato speciale e vengono
inseriti in ogni directory, il primo fa riferimento alla directory corrente e
particolare si riprenderà, approfondendolo sul piano dell'uso nelle funzioni
di libreria, il concetto di \textit{inode} di cui abbiamo brevemente accennato
le caratteristiche (dal lato dell'implementazione nel kernel) in
-\ref{sec:fileintr_vfs}.
+\secref{sec:fileintr_vfs}.
\subsection{Il funzionamento di un filesystem}
\label{sec:filedir_filesystem}
-Come già accennato in \ref{sec:fileintr_overview} linux (ed ogni unix in
+Come già accennato in \secref{sec:fileintr_overview} linux (ed ogni unix in
generale) organizza i dati che tiene su disco attraverso l'uso di un
filesystem. Una delle caratteristiche di linux rispetto agli altri unix è
quella di poter supportare grazie al VFS una enorme quantità di filesystem
funzioni che manipolano i file e le directory su cui torneremo fra poco; in
particolare è opportuno ricordare sempre che:
-\begin{itemize}
+\begin{enumerate}
\item L'\textit{inode} contiene tutte le informazioni riguardanti il file: il
tipo di file, i permessi di accesso, le dimensioni, i puntatori ai blocchi
associato, cioè quella che da qui in poi chiameremo una \textsl{voce}
(traduzione approssimata dell'inglese \textit{directory entry}, che non
useremo anche per evitare confusione con le \textit{dentries} del kernel di
- cui si parlava in \ref{sec:fileintr_vfs}).
+ cui si parlava in \secref{sec:fileintr_vfs}).
\item Come mostrato in \curfig si possono avere più voci che puntano allo
stesso \textit{inode}. Ogni \textit{inode} ha un contatore che contiene il
esistente, con la funzione \texttt{link}) al filesystem corrente.
\item Quando si cambia nome ad un file senza cambiare filesystem il contenuto
- del file non deve essere spostato, viene semplicemente creata una nuova
- \textit{dentry} per l'\textit{inode} in questione e rimossa la vecchia
- (questa è la modalità in cui opera normalmente il comando \texttt{mv}
- attraverso la funzione \texttt{rename}).
+ del file non deve essere spostato, viene semplicemente creata una nuova voce
+ per l'\textit{inode} in questione e rimossa la vecchia (questa è la modalità
+ in cui opera normalmente il comando \texttt{mv} attraverso la funzione
+ \texttt{rename}).
-\end{itemize}
+\end{enumerate}
Infine è bene avere presente che essendo file pure loro, esiste un numero di
riferimenti anche per le directories; per cui se ad esempio a partire dalla
\textit{hard link}). Il prototipo della funzione, definita in
\texttt{unistd.h}, e le sue caratteritiche principali, come risultano dalla
man page, sono le seguenti:
-\begin{itemize}
-\item \texttt{int link(const char * oldname, const char * newname)}
-
+\begin{prototype}{int link(const char * oldname, const char * newname)}
Crea un nuovo collegamento diretto al file indicato da \texttt{oldname}
dandogli nome \texttt{newname}.
La funzione restituisce zero in caso di successo e -1 per un errore, in caso
di errore. La variabile \texttt{errno} viene settata secondo i seguenti
codici di errore:
-
- \begin{itemize}
+ \begin{errlist}
\item \texttt{EXDEV} \texttt{oldname} e \texttt{newname} non sono sullo
stesso filesystem.
\item \texttt{EPERM} il filesystem che contiene \texttt{oldname} e
già.
\item \texttt{EMLINK} Ci sono troppi link al file \texttt{oldname} (il
numero massimo è specificato dalla variabile \texttt{LINK\_MAX}, vedi
- \ref{sec:xxx_limits}.
+ \secref{sec:xxx_limits}.
\item \texttt{ENOSPC} La directory in cui si vuole creare il link è piena e
non può essere ampliata.
\item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
su un filesystem montato readonly.
- \end{itemize}
-\end{itemize}
+ \end{errlist}
+\end{prototype}
La creazione di un nuovo collegamento diretto non copia il contenuto del file,
ma si limita ad aumentare di uno il numero di referenze al file aggiungendo il
nuovo nome ai precedenti. Si noti che uno stesso file può essere così
richiamato in diverse directory.
-Per quanto dicevamo in \ref{sec:filedir_filesystem} la creazione del
+Per quanto dicevamo in \secref{sec:filedir_filesystem} la creazione del
collegamento diretto è possibile solo se entrambi i pathname sono nello stesso
filesytem; inoltre il filesystem deve supportare i collegamenti diretti (non è
il caso ad esempio del filesystem \texttt{vfat} di windows).
La funzione opera sui file ordinari, come sugli altri oggetti del filesystem,
ma solo l'amministratore è in grado di creare un collegamento diretto ad
un'altra directory, questo lo si fa perché in questo caso è possibile creare
-dei cerchi nel filesystem (vedi \ref{sec:filedir_symlink}) che molti programmi
+dei cerchi nel filesystem (vedi \secref{sec:filedir_symlink}) che molti programmi
non sono in grado di gestire e la cui rimozione diventa estremamente
complicata (in genere occorre far girare il programma \texttt{fsck} per
riparare il filesystem).
-La rimozione di un file (o più precisamente di una sua dentry) si effettua con
-la funzione \texttt{unlink}; il suo prototipo, definito in \texttt{unistd.h} è
-il seguente:
+La rimozione di un file (o più precisamente della voce che lo referenzia) si
+effettua con la funzione \texttt{unlink}; il suo prototipo, definito in
+\texttt{unistd.h} è il seguente:
-\begin{itemize}
-\item \texttt{int unlink(const char * filename)}
-
+\begin{prototype}{int unlink(const char * filename)}
Cancella il nome specificato dal pathname nella relativa directory e
decrementa il numero di riferimenti nel relativo inode.
- La funzione restituisce zero in caso di successo e -1 per un errore, in caso
- di errore. La variabile \texttt{errno} viene settata secondo i seguenti
- codici di errore:
-
- \begin{itemize}
+ La funzione restituisce zero in caso di successo e -1 per un errore, nel
+ qual caso il file non viene toccato. La variabile \texttt{errno} viene
+ settata secondo i seguenti codici di errore:
+ \begin{errlist}
\item \texttt{EXDEV} \texttt{oldname} e \texttt{newname} non sono sullo
stesso filesystem.
\item \texttt{EPERM} il filesystem che contiene \texttt{oldname} e
già.
\item \texttt{EMLINK} Ci sono troppi link al file \texttt{oldname} (il
numero massimo è specificato dalla variabile \texttt{LINK\_MAX}, vedi
- \ref{sec:xxx_limits}.
+ \secref{sec:xxx_limits}.
\item \texttt{ENOSPC} La directory in cui si vuole creare il link è piena e
non può essere ampliata.
\item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
su un filesystem montato readonly.
- \end{itemize}
-\end{itemize}
-
-Per cancellare
-
-
-
+ \end{errlist}
+\end{prototype}
+Per cancellare una voce in una directory è necessario avere il permesso di
+scrittura su di essa (dato che si va a rimuovere una voce dal suo contenuto) e
+il diritto di esecuzione sulla directory che la contiene (torneremo in
+dettaglio sui permessi e gli attributi fra poco), se inoltre lo
+\textit{sticky} bit è settato occorerà anche essere proprietari del file o
+proprietari della directory (o root, per cui nessuna delle restrizioni è
+applicata).
Una delle caratteristiche di queste funzioni è che la creazione/rimozione
-della nnome dalla directory e l'incremento/decremento del numero di
+della nome dalla directory e l'incremento/decremento del numero di
riferimenti nell'inode deve essere una operazione atomica (cioè non
interrompibile da altri) processi, per questo entrambe queste funzioni sono
realizzate tramite una singola system call.
-
+Si ricordi infine che il file non viene eliminato dal disco fintanto che tutti
+i riferimenti ad esso sono stati cancellati, solo quando il \textit{link
+ count} mantenuto nell'inode diventa zero lo spazio occupato viene rimosso. A
+questo però si aggiunge una altra condizione, e cioè che non ci siano processi
+che abbiano detto file aperto. Come accennato questa proprietà viene spesso
+usata per essere sicuri di non lasciare file temporanei su disco in caso di
+crash dei programmi; la tecnica è quella di aprire il file e chiamare
+\texttt{unlink} subito dopo.
\subsection{Le funzioni \texttt{remove} e \texttt{rename}}
\subsection{I link simbolici}
\label{sec:filedir_sym_link}
-Siccome tutto ciò funziona facendo riferimento ad un inode, questa funzione
-può essere applicata soltanto per file che risiedono sullo stesso filesystem,
-(dato che solo in questo caso è garantita l'unicità dell'inode) e solo per
-filesystem di tipo unix. Inoltre in linux non è consentito eseguire un link
-diretto ad una directory.
+Siccome la funzione \texttt{link} crea riferimenti agli inodes, essa può
+funzionare soltanto per file che risiedono sullo stesso filesystem, dato che
+in questo caso è garantita l'unicità dell'inode, e solo per un filesystem di
+tipo unix. Inoltre in linux non è consentito eseguire un link diretto ad una
+directory se non si è root.
Per ovviare a queste limitazioni i sistemi unix supportano un'altra forma di
link (i cosiddetti \textit{soft link} o \textit{symbolic link}), che sono,
Le funzioni per operare sui link simbolici sono le seguenti, esse sono tutte
dichiarate nell'header file \texttt{unistd.h}.
-\begin{itemize}
-\item \texttt{int symlink(const char * oldname, const char * newname)}
-
+\begin{prototype}{int symlink(const char * oldname, const char * newname)}
Crea un nuovo link simbolico al file indicato da \texttt{oldname} dandogli
nome \texttt{newname}.
La funzione restituisce zero in caso di successo e -1 per un errore, in caso
di errore. La variabile \texttt{errno} viene settata secondo i codici di
errore standard di accesso ai files (trattati in dettaglio in
- \ref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
-
- \begin{itemize}
+ \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
+ \begin{errlist}
\item \texttt{EEXIST} Un file (o una directory) con quel nome esiste di
già.
\item \texttt{EROFS} La directory su cui si vuole inserire il nuovo link è
link è piena e non c'è ulteriore spazio disponibile.
\item \texttt{ELOOP} Ci sono troppi link simbolici nella risoluzione di
\texttt{oldname} o di \texttt{newname}.
- \end{itemize}
-\end{itemize}
+ \end{errlist}
+\end{prototype}
\subsection{Le funzioni \texttt{mkdir} e \texttt{rmdir}}
dell'analogo comando di shell \texttt{mkdir}; per accedere alla funzioni il
programma deve includere il file \texttt{sys/stat.h}.
-\begin{itemize}
-\item \texttt{char * mkdir (const char * dirname, mode\_t mode)}
-
+\begin{prototype}{char * mkdir (const char * dirname, mode\_t mode)}
Questa funzione crea una nuova directory vuota con il nome indicato da
\texttt{dirname}, assegnandole i permessi indicati da \texttt{mode}. Il nome
può essere indicato con il pathname assoluto o relativo.
La funzione restituisce zero in caso di successo e -1 per un errore, in caso
di errore \texttt{errno} viene settata secondo i codici di errore standard
di accesso ai files (trattati in dettaglio in
- \ref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
- \begin{itemize}
+ \secref{sec:filedir_access_control}) ai quali si aggiungono i seguenti:
+ \begin{errlist}
\item \texttt{EACCESS}
Non c'è il permesso di scrittura per la directory in cui si vuole inserire
la nuova directory.
la nuova directory.
\item \texttt{EROFS} La directory su cui si vuole inserire la nuova
directory è su un filesystem montato readonly.
- \end{itemize}
-\end{itemize}
+ \end{errlist}
+\end{prototype}
\subsection{Accesso alle directory}
la funzione \texttt{opendir} apre uno di questi stream e la funzione
\texttt{readdir} legge il contenuto della directory, i cui elementi sono le
\textit{directory entries} (da distinguersi da quelle della cache di cui
-parlavamo in \ref{sec:fileintr_vfs}) in una opportuna struttura
+parlavamo in \secref{sec:fileintr_vfs}) in una opportuna struttura
\texttt{struct dirent}.
Le funzioni qui descritte servono esaminare e cambiare la directory di lavoro
corrente. I prototipi di queste funzioni sono dichiarati in \texttt{unistd.h}.
-\begin{itemize}
-\item \texttt{char * getcwd (char * buffer, size\_t size)}
-
+\begin{prototype}{char * getcwd (char * buffer, size\_t size)}
Restituisce il filename completo della directory di lavoro corrente nella
stringa puntata da \texttt{buffer}, che deve essere precedentemente
allocata, per una dimensione massima di \texttt{size}. Si può anche
La funzione restituisce il puntatore \texttt{buffer} se riesce,
\texttt{NULL} se fallisce, in quest'ultimo caso la variabile
\texttt{errno} è settata con i seguenti codici di errore:
-
- \begin{itemize}
+ \begin{errlist}
\item \texttt{EINVAL} L'argomento \texttt{size} è zero e \texttt{buffer} non
è nullo.
\item \texttt{ERANGE} L'argomento \texttt{size} è più piccolo della
\item \texttt{EACCES} Manca il permesso di lettura o di ricerca su uno dei
componenti del pathname (cioè su una delle directory superiori alla
corrente).
- \end{itemize}
-\end{itemize}
+ \end{errlist}
+\end{prototype}
Di questa funzione esiste una versione \texttt{char * getwd(char * buffer)}
fatta per compatibilità all'indietro con BSD, che non consente di specificare
la dimensione del buffer; esso deve essere allocato in precedenza ed avere una
dimensione superiore a \texttt{PATH\_MAX} (di solito 256 byters, vedi
-\ref{sec:xxx_limits}; il problema è che in linux non esiste una dimensione
+\secref{sec:xxx_limits}; il problema è che in linux non esiste una dimensione
superiore per un pathname, per cui non è detto che il buffer sia sufficiente a
contenere il nome del file, e questa è la ragione principale per cui questa
funzione è deprecata.
e non solo tramite il filename; per questo motivo ci sono due diverse funzioni
per cambiare directory di lavoro.
-\begin{itemize}
-\item \texttt{int chdir (const char * pathname)}
-
+\begin{prototype}{int chdir (const char * pathname)}
Come dice il nome (che significa \textit{change directory}) questa funzione
serve a cambiare la directory di lavoro a quella speficata dal pathname
contenuto nella stringa \texttt{pathname}.
+\end{prototype}
-\item \texttt{int fchdir (int filedes)} analoga alla precedente, ma usa un
- file descriptor invece del pathname.
-
+\begin{prototype}{int fchdir (int filedes)}
+ Analoga alla precedente, ma usa un file descriptor invece del pathname.
Entrambe le funzioni restituiscono zero in caso di successo e -1 per un
errore, in caso di errore \texttt{errno} viene settata secondo i codici di
errore standard di accesso ai files (trattati in dettaglio in
- \ref{sec:filedir_access_control}) ai quali si aggiunge il codice
+ \secref{sec:filedir_access_control}) ai quali si aggiunge il codice
\texttt{ENOTDIR} nel caso il \texttt{filename} indichi un file che non sia
una directory.
-\end{itemize}
-
-
-
+\end{prototype}
%La struttura fondamentale che contiene i dati essenziali relativi ai file è il
%cosiddetto \textit{inode}; questo conterrà informazioni come il
%tipo di file (file di dispositivo, directory, file di dati, per un elenco
-%completo vedi \ntab), i permessi (vedi \ref{sec:file_perms}), le date (vedi
-%\ref{sec:file_times}).
+%completo vedi \ntab), i permessi (vedi \secref{sec:file_perms}), le date (vedi
+%\secref{sec:file_times}).
unix, è anzitutto opportuno fornire un'introduzione dettagliata su come essi
vengono trattati dal sistema. In particolare occorre tenere presente dov'è che
si situa il limite fondamentale fra kernel space e user space che tracciavamo
-al Cap.~\ref{cha:intro_unix}.
+al \capref{cha:intro_unix}.
Partiamo allora da come viene strutturata nel sistema la disposizione dei
file: per potervi accedere il kernel usa una apposita interfaccia che permetta
Sarà attraverso quest'ultimo che il kernel andrà a gestire l'accesso ai dati
memorizzati all'interno del disco stesso, strutturando l'informazione in files
e directory (su questo aspetto torneremo con maggiori dettagli in
-\ref{sec:filedir_filesystem}). Per poter accedere ai file contenuti in un
+\secref{sec:filedir_filesystem}). Per poter accedere ai file contenuti in un
disco occorrerà perciò attivare il filesystem, questo viene fatto
\textsl{montando} il disco (o la partizione del disco).
implementano le operazioni disponibili sul file. In questo modo i processi in
user space possono accedere alle operazioni attraverso detti metodi, che
saranno diversi a seconda del tipo di file (o dispositivo) aperto (su questo
-torneremo in dettaglio in \ref{sec:fileunix_fd}). Un elenco delle operazioni
+torneremo in dettaglio in \secref{sec:fileunix_fd}). Un elenco delle operazioni
previste dal kernel è riportato in \ntab.
\begin{table}[htb]
In unix è implementata da qualunque filesystem standard una forma elementare
(ma adatta alla maggior parte delle esigenze) di controllo di accesso ai
files. Torneremo sull'argomento in dettaglio più avanti (vedi
-\ref{sec:filedir_access_control}), qui ci limitiamo ad una introduzione dei
+\secref{sec:filedir_access_control}), qui ci limitiamo ad una introduzione dei
concetti essenziali.
Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo Unix,
Ad ogni file Unix associa sempre l'utente che ne è proprietario (il cosiddetto
\textit{owner}) e il gruppo di appartenenza, secondo il meccanismo degli uid e
-gid accennato in Sez.~\ref{sec:intro_usergroup}, e un insieme di permessi che
+gid accennato in \secref{sec:intro_usergroup}, e un insieme di permessi che
sono divisi in tre classi, e cioè attribuiti rispettivamente al proprietario,
a qualunque utente faccia parte del gruppo cui appartiene il file, e a tutti
gli altri utenti.
lettura, scrittura ed esecuzione (indicati rispettivamente con le lettere
\textit{w}, \textit{r} \textit{x}) applicabili rispettivamente al
proprietario, al gruppo, a tutti (una descrizione più dettagliata dei vari
-permessi associati ai file è riportata in \ref{sec:filedir_suid_sgid}). I
+permessi associati ai file è riportata in \secref{sec:filedir_suid_sgid}). I
restanti tre bit sono usati per indicare alcune caratteristiche più complesse
(\textit{suid}, \textit{sgid}, e \textit{sticky}) su cui pure torneremo in
-seguito (vedi \ref{sec:filedir_suid_sgid} e \ref{sec:filedir_stiky}).
+seguito (vedi \secref{sec:filedir_suid_sgid} e \secref{sec:filedir_stiky}).
Tutte queste informazioni sono tenute per ciascun file nell'inode. Quando un
processo cerca l'accesso al file esso controlla i propri uid e gid
In realtà il procedimento è più complesso di quanto descritto in maniera
elementare qui; inoltre ad un processo sono associati diversi identificatori,
-torneremo su questo in maggiori dettagli in seguito in \ref{sec:proc_perms}.
+torneremo su questo in maggiori dettagli in seguito in \secref{sec:proc_perms}.
\subsection{I tipi di files}
\label{sec:fileintr_file_types}
usare l'interfaccia standard di unix coi file descriptors. Allo stesso modo
devono essere usati i file descriptor se si vuole ricorrere a modalità
speciali di I/O come il polling o il non-bloccante (vedi
-\ref{sec:file_bohhhhh}).
+\secref{sec:file_bohhhhh}).
Gli stream forniscono un'interfaccia di alto livello costruita sopra quella
dei file descriptor, che tratta tutti i file nello stesso modo, con
accesso è un riferimento all'inode del file, pertanto anche se il file viene
cancellato da un altro processo, sarà sempre possibile mantenere l'accesso ai
dati, e lo spazio su disco non verrà rilasciato fintanto che il file non sarà
-chiuso e l'ultimo riferimento cancellato. È pertanto possibile (e pratica
-comune) aprire un file provvisorio per cancellarlo immediatamente dopo; in
-questo modo all'uscita del programma il file scomparirà definitivamente dal
-disco, ma il file ed il suo contenuto saranno disponibili per tutto il tempo
-in cui il processo è attivo.
+chiuso e l'ultimo riferimento cancellato. È pertanto possibile (come vedremo
+in dettaglio in \secref{sec:filedir_link}) aprire un file provvisorio per
+cancellarlo immediatamente dopo; in questo modo all'uscita del programma il
+file scomparirà definitivamente dal disco, ma il file ed il suo contenuto
+saranno disponibili per tutto il tempo in cui il processo è attivo.
Ritorneremo su questo più avanti, quando tratteremo l'input/output sui file,
esaminando in dettaglio come tutto ciò viene realizzato.
Una parte del kernel, lo \textit{scheduler}, si occupa di stabilire, ad
intervalli fissi e sulla base di un opportuno calcolo delle priorità, quale
-``processo'' (vedi Cap.~\ref{cha:process}) deve essere posto in esecuzione (il
+``processo'' (vedi \capref{cha:process}) deve essere posto in esecuzione (il
cosidetto \textit{prehemptive scheduling}), e questo verrà comunque eseguito
in modelità protetta; quando necessario il processo potrà accedere alle
risorse hardware soltanto attraverso delle opportune chiamate al sistema
Le periferiche infine vengono viste in genere attraverso un'interfaccia
astratta che permette di trattarle come fossero file. secondo il concetto per
-cui \textit{everything is a file}, vedi Cap.~\ref{cha:files_intro}, (questo
+cui \textit{everything is a file}, vedi \capref{cha:files_intro}, (questo
non è vero per le interfacce di rete, ma resta valido il concetto generale che
tutto il lavoro di accesso e gestione a basso livello è effettuato dal
kernel), mentre ai programmi vengono fornite solo delle routine di
é l'ambiente in cui viene eseguito il kernel. Ogni programma gira come se
avesse la piena disponibilità della macchina e della memoria ed è, salvo i
meccanismi di comunicazione previsti dall'architettura (che esamineremo nel
-Cap.~\ref{cha:IPC}) completamente ignaro del fatto che altri programmi possono
+\capref{cha:IPC}) completamente ignaro del fatto che altri programmi possono
essere messi in esecuzione dal kernel.
In questo non è possibile ad un singolo programma disturbare l'azione di un
dell'utente a cui appartiene ed impedire ad altri utenti di interferire con
esso. Inoltre con questo sistema viene anche garantita una forma base di
sicurezza interna in quanto anche l'accesso ai file (vedi
-Sez.~\ref{sec:fileintr_access_ctrl}) è regolato da questo meccanismo di
+\secref{sec:fileintr_access_ctrl}) è regolato da questo meccanismo di
identificazione.
Un utente speciale del sistema è \textit{root}, il cui uid è zero. Esso
% Command for section and chapters
%
\newcommand{\capref}[1]{cap.~\ref{#1}}
-\newcommand{\sezref}[1]{sez.~\ref{#1}}
-
+\newcommand{\secref}[1]{sez.~\ref{#1}}
%
% Macro to create a special environment for function prototypes
%
-\newenvironment{prototype}[1]{\begin{itemize}
- \item \texttt{#1}}{\end{itemize}}
-\newenvironment{errlist}{\begin{itemize}}{\end{itemize}}
+\newenvironment{prototype}[1]{
+ \center
+ \begin{minipage}[c]{14cm}
+ \par \texttt{#1}
+ \footnotesize
+ \begin{list}{}{}
+ \item }
+{ \end{list}
+ \par
+\normalsize
+\par \texttt{ }
+\end{minipage}
+\par
+}
+\newenvironment{errlist}{\begin{description}}{\end{description}}
-%%
+%%
%% GaPiL : Guida alla Programmazione in Linux
-%%
+%%
%% S. Piccardi Feb. 2001
%%
%% main.tex: file principale, gli altri vanno inclusi da questo.
\usepackage{color}
%
% Setting page layout
-%
+%
\oddsidemargin=0.5cm
\evensidemargin=-0.5cm
\textwidth=16cm
A copy of the license is included in the section entitled ``GNU
Free Documentation License''.
+
\end{quote}
\clearemptydoublepage
\pagenumbering{arabic}
-
\lstset{language=C++}
\lstset{basicstyle=\small,
\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.
+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}
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}
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{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
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
\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}.
+ \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
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
\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.
+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: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.
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
effettuato per entrambe le direzioni di comunicazione.
Una descrizione più accurata del protocollo è fornita in appendice
-\ref{cha:tcp_protocol}.
+\capref{cha:tcp_protocol}.
\subsection{Limiti e dimensioni riguardanti la trasmissione dei dati}
\label{sec:net_lim_dim}
\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
- \ref{sec:appA_ipv4head}).
+ \secref{sec:appA_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
\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 \ref{cha:ip_protcol}}), in blocchi più piccoli che possono
-essere trasmessi attraverso l'interfaccia.
+ opzione, si veda \secref{cha:ip_protcol}}), in blocchi più piccoli che
+possono essere trasmessi attraverso l'interfaccia.
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
Se arriva un segnale per il quale non è stato specificata un'azione viene
utilizzata l'azione standard. Questa è diversa da segnale a segnale (come
-vedremo in \ref{sec:sig_standard}) ma per la maggior parte essa comporta la
+vedremo in \secref{sec:sig_standard}) ma per la maggior parte essa comporta la
terminazione del processo, per alcuni che invece rappresentano eventi innocui
l'azione standard è di non fare nulla.
(e non solo). Il socket costituisce in sostanza un canale di comunicazione fra
due processi su cui si possono leggere e scrivere dati analogo a quello di una
pipe ma a differenza di questa e degli altri meccanismi esaminati nel capitolo
-\ref{cha:IPC} i socket non sono limitati alla comunicazione fra processi che
-girano sulla stessa macchina ma possono effettuare la comunicazione anche
+\capref{cha:IPC} i socket non sono limitati alla comunicazione fra processi
+che girano sulla stessa macchina ma possono effettuare la comunicazione anche
attraverso la rete.
Quella dei socket costituisce infatti la principale API (\textit{Application
\label{sec:sock_gen}
Per capire il funzionamento dei socket occorre avere presente il funzionamento
-dei protocolli di rete (vedi \ref{cha:network}), ma l'interfaccia è del tutto
-generale e benché le problematiche (e quindi le modalità di risolvere i
+dei protocolli di rete (vedi \capref{cha:network}), ma l'interfaccia è del
+tutto generale e benché le problematiche (e quindi le modalità di risolvere i
problemi) siano diverse a seconda del tipo di protocollo di comunicazione
usato, le funzioni da usare restano le stesse.
Il prototipo della funzione è definito nell'header \texttt{sys/socket.h}, la
funzione prende tre parametri, il dominio del socket (che definisce la
-famiglia di protocolli, vedi \ref{sec:sock_domain}), il tipo di socket (che
-definisce lo stile di comunicazione vedi \ref{sec:sock_type}) e il protocollo;
-in genere quest'ultimo è indicato implicitamente dal tipo di socket, per cui
-viene messo a zero (con l'eccezione dei \textit{raw socket}).
+famiglia di protocolli, vedi \secref{sec:sock_domain}), il tipo di socket (che
+definisce lo stile di comunicazione vedi \secref{sec:sock_type}) e il
+protocollo; in genere quest'ultimo è indicato implicitamente dal tipo di
+socket, per cui viene messo a zero (con l'eccezione dei \textit{raw socket}).
\begin{itemize}
\item \texttt{int socket(int domain, int type, int protocol)}
porta viene settato al numero di protocollo.
Il membro \texttt{sin\_family} deve essere sempre settato; \texttt{sin\_port}
-specifica il numero di porta (vedi \ref{sec:TCPel_port_num}; i numeri di porta
-sotto il 1024 sono chiamati \textsl{riservati} in quanto utilizzati da servizi
-standard. Soltanto processi con i privilegi di root (effective uid uguale a
-zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} possono usare la
-funzione \texttt{bind} su queste porte.
+specifica il numero di porta (vedi \secref{sec:TCPel_port_num}; i numeri di
+porta sotto il 1024 sono chiamati \textsl{riservati} in quanto utilizzati da
+servizi standard. Soltanto processi con i privilegi di root (effective uid
+uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} possono
+usare la funzione \texttt{bind} su queste porte.
Il membro \texttt{sin\_addr} contiene l'indirizzo internet dell'altro capo
della comunicazione, e viene acceduto sia come struttura (un resto di una
essere specificati in quello che viene chiamato \textit{network order}, cioè
con i bit ordinati in formato \textit{big endian}, questo comporta la
necessità di usare apposite funzioni di conversione per mantenere la
-portabilità del codice (vedi \ref{sec:sock_addr_func} per i dettagli del
+portabilità del codice (vedi \secref{sec:sock_addr_func} per i dettagli del
problema e le relative soluzioni).
\subsection{La struttura degli indirizzi IPv6}
in tre parti di cui i 24 bit inferiori indicano l'etichetta di flusso, i
successivi 4 bit la priorità e gli ultimi 4 sono riservati; questi valori
fanno riferimento ad alcuni campi specifici dell'header dei pacchetti IPv6
-(vedi \ref{sec:appA_ipv6}) ed il loro uso è sperimentale.
+(vedi \secref{sec:appA_ipv6}) ed il loro uso è sperimentale.
Il campo \texttt{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
infine il campo \texttt{sin6\_scope\_id} è un campo introdotto con il kernel