l'indicazione di quale dispositivo contiene il filesystem da usare come punto
di partenza e questo viene montato come radice dell'albero (cioè nella
directory \texttt{/}); tutti gli ulteriori dischi devono poi essere inseriti
-nell'albero utilizzando opportune sottodirectory (in genere sotto
+nell'albero utilizzando opportune subdirectory (in genere sotto
\texttt{/mnt}) .
Alcuni filesystem speciali (come \texttt{/proc} che contiene un'interfaccia ad
All'interno dello stesso albero si potranno poi inserire anche gli altri
oggetti visti attraverso l'interfaccia che manipola i files come le FIFO, i
-link, i socket e gli stessi i file di dipositivo (questi ultimi, per
+link, i socket e gli stessi i file di dispositivo (questi ultimi, per
convenzione, sono inseriti nella directory \texttt{/dev}).
\subsection{Il \textit{virtual filesystem} di linux}
kernel (\texttt{linux/Documentation/vfs.txt}).
L'argomento è abbastanza ``esoterico'' e questa sezione può essere saltata ad
-una prima lettura; è bene però tenere presente che vengono intodotti qui
-alcuni termini che potranno comparire in seguito, come \textit{imode},
+una prima lettura; è bene però tenere presente che vengono introdotti qui
+alcuni termini che potranno comparire in seguito, come \textit{inode},
\textit{dentry}, \textit{dcache}.
In linux il concetto di \textit{everything is a file} è stato implementato
L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
una struttura di tipo \texttt{file} in cui viene inserito un puntatore alla
-dentry e una struttura \verb|f_ops| che contiene i puntatotori ai metodi che
+dentry e una struttura \verb|f_ops| che contiene i puntatori ai metodi che
implementano le operazioni disponibili sul file. In questo modo i processi in
-use space possono accedere alle operazioni attraverso detti metodi, che
+user space possono accedere alle operazioni attraverso detti metodi, che
saranno diversi a seconda del tipo di file (o dispositivo) aperto. Un elenco
delle operazioni disponibili è riportato in \ntab.
\begin{table}[htb]
\centering
- \begin{tabular}[c]{c l}
+ \begin{tabular}[c]{c p{7cm}}
\textbf{funzione} & \textbf{operazione} \\
\hline
- open & apre il file \\
- read & legge dal file \\
- write & scrive sul file \\
- llseek & sposta la posizione corrente sul file \\
- ioctl & accede alle operazioni di controllo (tramite la \texttt{ioctl})\\
- readdir & per leggere il contenuto di una directory \\
- poll & \\
- mmap & chiamata dalla system call \texttt{mmap} \\
- release & chiamata quando l'ultima referenza a un file aperto è chiusa\\
- fsync & chiamata dalla system call \texttt{fsync} \\
- fasync & chiamate da \texttt{fcntl} quando è abilitato il modo asincrono
- per l'I/O su file. \\
+ \textit{open} & apre il file \\
+ \textit{read} & legge dal file \\
+ \textit{write} & scrive sul file \\
+ \textit{llseek} & sposta la posizione corrente sul file \\
+ \textit{ioctl} & accede alle operazioni di controllo
+ (tramite la \texttt{ioctl})\\
+ \textit{readdir} & per leggere il contenuto di una directory \\
+ \textit{poll} & \\
+ \textit{mmap} & chiamata dalla system call \texttt{mmap}.
+ mappa il file in memoria\\
+ \textit{release} & chiamata quando l'ultima referenza a un file
+ aperto è chiusa\\
+ \textit{fsync} & chiamata dalla system call \texttt{fsync} \\
+ \textit{fasync} & chiamate da \texttt{fcntl} quando è abilitato
+ il modo asincrono per l'I/O su file. \\
\hline
\end{tabular}
\caption{Operazioni sui file definite nel VFS.}
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 dettaglo più avanti, qui ci limitiamo ad
+files. Torneremo sull'argomento in dettaglio più avanti, qui ci limitiamo ad
una introduzione dei concetti essenziali.
Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo unix,
\begin{table}[htb]
\begin{center}
- \begin{tabular}[c]{l l l}
+ \begin{tabular}[c]{l l p{7cm}}
+ \multicolumn{2}{c}{\textbf{Nome}} & \textbf{Descrizione} \\
+ \hline
\textit{regular file} & \textsl{file normale} &
un file che contiene dei dati (l'accezione normale di file) \\
\textit{directory} & \textsl{cartella o direttorio} &
\textit{fifo} & \textsl{tubo} &
un file speciale che identifica una linea di comunicazione software
(unidirezionale) \\
- \textit{socket} & \textsl{presa}
+ \textit{socket} & \textsl{presa} &
un file speciale che identifica una linea di comunicazione software
(bidirezionale) \\
+ \hline
\end{tabular}
\caption{Tipologia dei file definiti nel VFS}
\label{tab:file_types}
Per poter accedere al contenuto dei file occorre anzitutto aprirlo. Questo
crea un canale di comunicazione che permette di eseguire una serie di
operazioni. Una volta terminate le operazioni, il file dovrà essere chiuso, e
-questo chiuderà il canale di comuniczione impedendo ogni ulteriore operazione.
+questo chiuderà il canale di comunicazione impedendo ogni ulteriore operazione.
\subsection{Le due interfacce ai file}
\label{sec:file_base_api}
-In unix le modalità di accesso ai file e le relative insterfacce di
+In unix le modalità di accesso ai file e le relative interfacce di
programmazione sono due, basate su due diversi meccanismi di connessione.
La prima è quella dei cosiddetti \textit{file descriptor} (descrittore di
file), che è specifica di unix e che provvede un accesso diretto a basso
livello non bufferizzato, con un'interfaccia primitiva ed essenziale; i file
-descriptors sono rappresetati da numeri interi (cioè semplici variabili di
+descriptors sono rappresentati da numeri interi (cioè semplici variabili di
tipo \texttt{int}). L'interfaccia è definita nell'header \texttt{unistd.h}.
La seconda è quella degli \textit{stream}, che provvede un'interfaccia più
-complessa e un'accesso bufferizzato, questa è anche l'intefaccia standard
-usata dal linguaggio C e che perciò si trova anche su tutti i sistemi non
-unix. Gli stream sono più complessi e sono rappresentati da puntatori ad un
-opportuno oggetto, cioè del tipo \texttt{FILE *}. L'interfaccia è definita
-nell'header \texttt{stdio.h}.
+evoluta e un accesso bufferizzato. Questa è anche l'interfaccia standard usata
+dal linguaggio C e perciò si trova anche su tutti i sistemi non unix. Gli
+stream sono oggetti complessi e sono rappresentati da puntatori ad un
+opportuna struttura definita dalle librerie del C, si accede ad essi sempre in
+maniera indiretta utilizzando il tipo \texttt{FILE *}. L'interfaccia è
+definita nell'header \texttt{stdio.h}.
Entrambe le interfacce possono essere usate per l'accesso ai file come agli
altri oggetti del VFS (pipes, socket, device), ma per poter accedere alle
operazioni di controllo sul particolare tipo di oggetto del VFS scelto occorre
usare l'interfaccia a basso livello dei file descriptor. 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}).
+speciali di I/O come il polling o il non-bloccante (vedi
+\ref{sec:file_bohhhhh}).
-Gli stream però forniscono un'interfaccia di alto livello costruita sopra
-quella dei file descriptor, e tratta tutti i file nello stesso modo, con
+Gli stream forniscono un'interfaccia di alto livello costruita sopra quella
+dei file descriptor, che tratta tutti i file nello stesso modo, con
l'eccezione di poter scegliere tre diversi stili di bufferizzazione. Il
maggior vantaggio degli stream è che l'interfaccia per le operazioni di
input/output è enormemente più ricca di quella dei file descriptor, che
provvedono solo funzioni elementari per la lettura/scrittura diretta di
blocchi di bytes. In particolare dispongono di tutte le funzioni di
formattazione per l'input e l'output adatte per manipolare anche i dati in
-forma di linee o singoli caratteri.
+forma di linee o singoli caratteri.
In ogni caso, dato che gli stream sono implementati sopra l'interfaccia a
-basso livello dei file decriptor, è sempre possibile extrarre il file
+basso livello dei file descriptor, è sempre possibile estrarre il file
descriptor da uno stream ed eseguirvi operazioni di basso livello, o associare
in un secondo tempo uno stream ad un file descriptor.
-In generale, se non necessitano specificamente le funzionalità di basso
+In generale, se non necessitano specificatamente le funzionalità di basso
livello, è opportuno usare sempre gli stream per la loro maggiore portabilità
-essendo questi ultimi definito nello stadard ISO C; l'interfaccia con i file
+essendo questi ultimi definito nello standard ISO C; l'interfaccia con i file
descriptor invece segue solo lo standard POSIX.1 dei sistemi unix ed è
pertanto di portabilità più limitata.
\label{sec:files_spec_unix}
Essendo un sistema multitasking e multiutente esistono alcune caratteristiche
-specifiche di unix che devono essere tenute in conto nell'acceso ai file. È
+specifiche di unix che devono essere tenute in conto nell'accesso ai file. È
infatti normale che più processi o programmi possano accedere
contemporaneamente allo stesso file e devono poter eseguire le loro operazioni
indipendentemente da quello che fanno gli altri processi.
indipendente.
Questo ha delle conseguenze di cui è bene tenere conto; ad esempio in tutti i
-sistemi POSIX uno degli attibuti di un file aperto è la posizione corrente nel
+sistemi POSIX uno degli attributi di un file aperto è la posizione corrente nel
file, cioè il punto nel file in cui verrebbe letto o scritto alla operazione
successiva. Essa è rappresentata da un numero intero che indica il numero di
bytes dall'inizio del file, che viene (a meno che non si apra il file in
append) inizializzato a zero all'apertura del medesimo.
-Questo è uno dei dati che viene mantento nella suddetta struttura, per cui
+Questo è uno dei dati che viene mantenuto nella suddetta struttura, per cui
ogni processo avrà la sua posizione corrente nel file, che non sarà
influenzata da quello che altri processi possono fare. Anzi, aprire un file
-significa appuntio creare ed inizializzare una tale struttura, per cui se si
+significa appunto creare ed inizializzare una tale struttura, per cui se si
apre due volte lo stesso file all'interno dello stesso processo, si otterrano
-due file descriptor o due stream che avreanno ancora un posizione corrente nel
-file assolutamente independente.
+due file descriptor o due stream che avranno ancora un posizione corrente nel
+file assolutamente indipendente.
Si tenga conto inoltre che un'altro dei dati contenuti nella struttura di
accesso è un riferimento all'inode del file, pertanto anche se il file viene
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 scomparità definitivamente dal disco, ma il
+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.
-\subsection{L'accesso ai files: nomi e direcory}
+\subsection{L'accesso ai files: nomi e directory}
\label{sec:file_names}
L'organizzazione dei nomi dei file deriva direttamente dall'organizzazione dei
Il processo con cui si associa ad un pathname uno specifico file (cioè si
identifica l'inode a cui fare riferimento) è chiamato risoluzione del nome
-(\textit{file name resoluzion} o \textit{pathname resolution}).
+(\textit{file name resolution} o \textit{pathname resolution}).
La risoluzione viene fatta esaminando il pathname da destra a sinistra e
localizzando ogni componente nella directory indicata dal componente
-precedente: ovviamente perchè il procedimento funzioni occorre che i
+precedente: ovviamente perché il procedimento funzioni occorre che i
componenti indicati come directory esistano e siano effettivamente directory,
-inoltre i permessi devono consenite l'accesso.
+inoltre i permessi devono consentire l'accesso.
Se il pathname comincia per \texttt{/} la ricerca parte dalla directory radice
la stessa per tutti i processi ed equivale alla radice dell'albero
(\ref{sec:file_gen}): in questo caso si parla di un pathname
\textsl{assoluto}. Altrimenti la ricerca parte dalla directory di lavoro
-corrente (\texit{current working directory}, su cui pure torneremo più avanti)
+corrente (\textit{current working directory}, su cui pure torneremo più avanti)
ed il pathname è detto \textsl{relativo}.
I componenti \texttt{.} e \texttt{..} hanno un significato speciale e vengono
-inseriti in ogni directory;
+inseriti in ogni directory, il primo fa riferimento alla directory corrente e
+il secondo alla directory \textsl{genitore} (\textit{parent directory}) cioè
+la directory che contiene il riferimento alla directory corrente; nel caso
+questa sia la directory radice allora il riferimento è a se stessa.
+
+Infine si ricordi che in unix non esistono i tipi di file e che non c'è nessun
+supporto per le estensioni come parte del filesystem. Ciò non ostante molti
+programmi adottano delle convenzioni per i nomi dei file, ad esempio il codice
+C normalmente si mette in file con l'estensione .c, ma questa è solo una
+convenzione.
+
+
+\section{I file stream}
+\label{sec:file_stream}
+
+Esamineremo in questa sezione l'interfaccia per i file stream, le modalità per
+crearli, e le funzioni disponibili per leggere, scrivere e compiere le varie
+operazioni connesse all'uso dei file. L'interfaccia è accessibile includendo
+l'header file \texttt{stdio.h}.
+
+Per ragioni storiche la struttura di dati che rappresenta un stream è stata
+chiamata \texttt{FILE}, dato che le funzioni di libreria usano sempre come
+parametri oggetti di tipo \texttt{FILE *} alle volte si usa il termine
+puntatore a file come sinonimo di stream.
+
+
+
%La struttura fondamentale che contiene i dati essenziali relativi ai file è 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}).
+
il capitolo.
\section{La struttura di un sistema Unix}
-\label{sec:unix_struct}
+\label{sec:intro_unix_struct}
Il concetto base di unix é quello di un nucleo del sistema (il cosiddetto
\textit{kernel}) a cui si demanda la gestione delle risorse essenziali (la
%
% Setting page layout
%
-
\oddsidemargin=0.5cm
\evensidemargin=-0.5cm
\textwidth=16cm
\textheight=24.2cm
\topmargin=-1.cm
%\setcaptionmargin{2cm}
-
%\renewcommand{\chaptername}{Capitolo}
%\renewcommand{\contentsname}{Indice}
%\renewcommand{\bibname}{Bibliografia}
%\includeonly{macro,pref,intro,fdl}
-
\title{Guida alla Programmazione in Linux.}
-\author{Simone Piccardi,
- si spera anche qualcun'altro}
+\author{Simone Piccardi}
\begin{document}
-
-
\pagenumbering{roman}
\maketitle
\include{intro}
\include{files}
-\include{network}
\include{process}
\include{option}
\include{signal}
\include{ipc}
+\include{network}
+\include{socket}
\include{fdl}
% at the end put the bibliography
\chapter{Introduzione alla rete}
+\label{cha:network}
-In questo capitolo sarà fatta un'introduzione ai contetti generali che
-servono come prerequisiti per capire ed
-esamineremo a grandi linee i protocolli di rete e come questi sono organizzati
-e interagiscono.
+In questo capitolo sarà fatta un'introduzione ai contetti generali che servono
+come prerequisiti per capire la programmazione di rete ed esamineremo a grandi
+linee i protocolli di rete e come questi sono organizzati e interagiscono.
+
+In particolare, avendo assunto l'ottica di un'introduzione mirata alla
+programmazione di rete, ci concentreremo sul protocollo più diffuso che è
+quello che sta alla base di internet, ed in particolare sulle parti più
+importanti ai fini della programmazione.
\section{I protocolli di rete}
-\label{sec:layer}
+\label{sec:net_protocols}
Parlando di reti di computer si parla in genere di un insieme molto vasto ed
-eterogeneo di mezzi di comunicazione che vanno dal cavo telefonico, alla
-fibra ottica, alle comunicazioni via satellite; per rendere possibile la
+eterogeneo di mezzi di comunicazione che vanno dal cavo telefonico, alla fibra
+ottica, alle comunicazioni via satellite; per rendere possibile la
comunicazione attraverso un così variegato insieme di mezzi sono stati
adottati una serie di protocolli, il più famoso dei quali, quello alla base
-del funzionamento di internet, é il cosiddetto TCP/IP.
+del funzionamento di internet, è il cosiddetto TCP/IP.
\subsection{Il modello ISO/OSI}
-\label{sec:iso_osi}
+\label{sec:net_iso_osi}
Una caratteristica comune dei protocolli di rete è il loro essere strutturati
in livelli sovrapposti; in questo modo un livello superiore esegue richieste
al livello sottostante e da questo riceve responsi, mentre livelli uguali su
macchine diverse conversano tramite lo stesso protocollo. Questo modello di
-funzionamento è stato stato standardizzato dalla International Standards
-Organization (ISO) che ha preparato fin dal 1984 il Modello di Riferimento
-Open Systems Interconnection (OSI), strutturato in a sette livelli, secondo la
-tabella in \ntab.
+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.
\begin{table}[htb]
\centering
\hline
\end{tabular}
\caption{I sette livelli del protocollo ISO/OSI.}
-\label{tab:osilayers}
+\label{tab:net_osilayers}
\end{table}
Il modello ISO/OSI è stato sviluppato corrispondentemente alla definizione
il lavoro dettagliato di standardizzazione il modello si è rivelato
sostanzialmente troppo complesso e poco flessibile rispetto a quello,
precedente, su cui si basa TCP/IP che è diventato uno standard de facto;
-quest'ultimo viene comunemente chiamato modello DoD (Department of Defense),
-dato che fu sviluppato dall'agenzia ARPA per il Dipartimento della Difesa
-Americano.
+quest'ultimo viene comunemente chiamato modello DoD (\textit{Department of
+ Defense}), dato che fu sviluppato dall'agenzia ARPA per il Dipartimento
+della Difesa Americano.
-\subsection{Il protocollo TCP/IP}
-\label{sec:tcpip_overview}
+\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
anche la corrispondenza fra i rispettivi livelli (che comunque è
-approssimativa) e come essi vanno ad inserirsi all'interno del sistema
-operativo, riguardo alla divisione fra user space e kernel space spiegata in
-\ref{sec:unix_struct}.
-
-% L'attuale Internent Protocol (IPv4) viene standardizzato nel 1981
-% dall'RFC~719; esso 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.).
-
-% In realtà IP realizza solo una parte di tutto questo, e fa parte di un
-% sistema che va sotto il nome di TCP/IP che è,
-% uno di
-% questi, quello responsabile del trasporto dei pacchetti fra le varie reti che
-% compongono Internet, è appunto IP.
+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}.
\begin{table}[htb]
\centering
\hline
\end{tabular}
\caption{I quattro livelli del protocollo TPC/IP.}
-\label{tab:layers}
+\label{tab:net_layers}
\end{table}
\begin{description}
\item \textbf{Applicazione} É relativo ai programmi di interfaccia utente, in
genere questi vengono realizzati secondo il modello Client-Server (vedi
- \ref{sec:cliserv}.
+ \ref{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
\subsection{Criteri generali del design di TCP/IP}
-
+\label{sec:net_tcpip_design}
La filosofia architetturale di TCP/IP è semplice: costruire una rete che
possa sopportare il carico in transito, ma permettere ai singoli nodi di
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,
+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.
+
+\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.
+
+La figura è da fare ...
+
+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
+ 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
+ lo stesso servizio di trasporto di IPv4 per i pacchetti TCP, UDP e ICPMv6.
+\item \textsl{TCP} \textit{Trasmission Control Protocol}. È un protocollo
+ 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.
+\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'è
+ garanzia che i pacchetti raggiungano la loro destinazione, né sull'eventuale
+ 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
+ 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
+ protocollo usato per il \textit{multicasting} (vedi
+ \ref{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
+ FDDI ma non serve in connessioni punto-punto.
+\item \textsl{RARP} \textit{Reverse Address Resolution Protocol}. È il
+ protocollo che mappa un indirizzo hardware in un indirizzo IP. Viene usato a
+ volte per durante il boot per assegnare un indirizzo IP ad una macchina.
+\item \textsl{ICMPv6} \textit{Internet Control Message Protocol, version 6}.
+ Combina per IPv6 le funzionalità di ICMPv4, IGMP e ARP.
+\item \textsl{NETLINK} \textit{Netlink}.
+ Provvede l'interfaccia di accesso alla comunicazione a basso livello.
+\end{list}
+
+Gran parte delle applicazioni comunicano usando TCP o UDP, ed alcune si
+rifanno ad IP (ed i suoi correlati ICMP e IGMP); benché sia TCP che UDP siano
+basati su IP e sia possibile intervenire a questo livello con i \textit{raw
+ socket} questa tecnica è molto meno diffusa e a parte applicazioni
+particolari si preferisce sempre usare i servizi messi a disposizione dai due
+protocolli precedenti. Per questo motivo a parte alcuni brevi accenni su IP
+in questa sezione ci concentreremo sul livello di trasporto.
+
+\subsection{Internet Protocol (IP)}
+\label{sec:net_ip}
+
+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
+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.).
+Il compito di IP è pertanto quello di trasmettere i pacchetti da un computer
+all'altro della rete; le caratteristiche essenziali con cui questo viene
+realizzato in IPv4 sono due:
+
+\begin{itemize}
+\item \textit{Universal addressing} la comunicazione avviene fra due host
+ identificati univocamente con un indirizzo a 32 bit che può appartenere ad
+ una sola interfaccia di rete.
+\item \textit{Best effort} viene assicurato il massimo impegno nella
+ trasmissione, ma non c'è nessuna garanzia per i livelli superiori né sulla
+ percentuale di successo né sul tempo di consegna dei pacchetti di dati.
+\end{itemize}
+
+Negli anni '90 la crescita vertiginosa del numero di macchine connesse a
+internet ha iniziato a far emergere i vari limiti di IPv4, per risolverne i
+problemi si è perciò definita una nuova versione del protocollo, che (saltando
+un numero) è diventata la versione 6. IPv6 nasce quindi come evoluzione di
+IPv4, mantendone inalterate le funzioni che si sono dimostrate valide,
+eliminando quelle inutili e aggiungendone poche altre ponendo al contempo una
+grande attenzione a mantenere il protocollo il più snello e veloce possibile.
+
+I cambiamenti apportati sono comunque notevoli e si possono essere riassunti a
+grandi linee nei seguenti punti:
+\begin{itemize}
+\item l'espansione delle capacità di indirizzamento e instradamento, per
+ 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}
+\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
+\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'')
+\end{itemize}
+
+Per maggiori dettagli riguardo al protocollo si può consultare
+\ref{sec:appA_ip}.
+
+
+\subsection{UDP: User Datagram Protocol)}
+\label{sec:net_udp}
+
+
+\subsection{TCP: Transport Control Protocol)}
+\label{sec:net_tcp}
+
+
\section{Il modello client-server}
-\label{sec:cliserv}.
+\label{sec:net_cliserv}.
La differenza principale fra un'applicazione di rete e un programma normale
è che quest'ultima per definizione concerne la comunicazione fra
processo.
In genere i segnali vengono usati dal kernel per riportare situazioni
-eccezionali (come errori di accesso, eccezioni atritmetiche, etc.) ma possono
+eccezionali (come errori di accesso, eccezioni aritmetiche, etc.) ma possono
anche essere usati come forma elementare di comunicazione fra processi (ad
esempio vengono usati per il controllo di sessione), per notificare eventi
(come la terminazione di un processo figlio), etc.
essere perso o causare il comportamento originale (in genere la terminazione
del processo). Questa è la ragione per cui detti segnali sono chiamati
\textit{inaffidabili}, in quanto la ricezione del segnale e la reinstallazione
-del suo manipolatore non sono oiperazioni atomiche.
+del suo manipolatore non sono operazioni atomiche.
In caso di implementazione inaffidabile le chiamate di sistema non sono fatte
ripartire automaticamente quando sono interrotte da un segnale, per questo il
In caso di segnali \textit{reliable} invece il signal handler resta installato
quando viene chiamato e i problemi precedenti sono evitati. Inoltre alcune
-chiamate di sisteme possono essere fatte ripartire automaticamente e si può
+chiamate di sistema possono essere fatte ripartire automaticamente e si può
ottenere un'operazione di pausa atomica (usando la funzione POSIX
\texttt{sigsuspend}).
\label{sec:sig_types}
-In generale gli eventi che generano i segnali si possono diviedere in tre
+In generale gli eventi che generano i segnali si possono dividere in tre
categorie principali: errori, eventi e richieste esplicite.
Un errore significa che un programma ha fatto qualcosa di sbagliato e non può
\end{itemize}
Il programma può specificare queste scelte usano le due routine
-\texttt{signal} e \texttt{sigaction}; se si è installato un manipalatore sarà
+\texttt{signal} e \texttt{sigaction}; se si è installato un manipolatore sarà
quest'ultimo a intercettare il segnale ed ad essere eseguito, e mentre viene
eseguito (onde evitare race conditions) il segnale viene bloccato.
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
-terminazione del processo, per alcuni che invece rappresentano eventi innoqui
+terminazione del processo, per alcuni che invece rappresentano eventi innocui
l'azione standard è di non fare nulla.
Quando un segnale termina un processo, il padre può determinare la causa della
violazioni di accesso) hanno anche la caratteristica di scrivere un file
\textit{core dump} che registra lo stato del processo prima della terminazione
e può essere esaminato da un debugger per investigare sulla causa dell'errore.
-Lo stesso avvine se i suddetti segnale vengono generati artificialmente con
+Lo stesso avviene se i suddetti segnale vengono generati artificialmente con
una \texttt{kill}.
Il numero totale di segnali presenti è dato dalla macro \texttt{NSIG}, e dato
che i numeri dei segnali sono allocati progressivamente, essa corrisponde
-anche al successivo del valore numerico assegnato al'ultimo segnale definito.
+anche al successivo del valore numerico assegnato all'ultimo segnale definito.
\subsubsection{Segnali di errore di programma}
-Questi segnali sono generati quando c'é un grave errore nel programma rilevato
+Questi segnali sono generati quando c'è un grave errore nel programma rilevato
dal sistema o dallo stesso hardware. In generale indicano che il programma ha
dei gravi problemi e l'esecuzione non può essere proseguita.
Alcuni programmi usano questi segnali per riordinare le cose prima di uscire.
-As esempio ripristinare i settaggi della console, o eliminare i file di lock.
+Ad esempio ripristinare i settaggi della console, o eliminare i file di lock.
In questo caso il manipolatore deve concludersi ripristinando l'azione di
default e rialzando il segnale, così che il programma possa concludersi come
se il manipolatore non ci fosse mai stato.
Questi segnali sono:
\begin{itemize}
-\item \texttt{SIGFPE} Riporta un errore aritmetico fatale. Benchè il nome
+\item \texttt{SIGFPE} Riporta un errore aritmetico fatale. Benché il nome
derivi da \textit{floating point exception} si applica a tutti gli errori
- aritmetici comprea la divisione per zero e l'overflow.
+ aritmetici compresa la divisione per zero e l'overflow.
% Per questo segnale le cose sono complicate dal fatto che possono esserci
% molte diverse eccezioni che \texttt{SIGFPE} non distingue, mentre lo
--- /dev/null
+\chapter{Socket}
+\label{cha:socket}
+
+I \textit{socket} sono usati come meccanismo di comunicazione fra programmi
+utilizzato in ambito unix (e non solo). La creazione di un socket restituisce
+un file descriptor 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 attraverso la rete.
+
+I socket infatti sono la principale API (\textit{Application Program
+ Interface}) usata nella programmazione di rete. La loro origine risale al
+1983, quando furono introdotti nel BSD 4.2; l'interfaccia è rimasta
+sostanzialmente la stessa con piccole modifiche negli anni successivi. Benché
+siano state sviluppate interfacce alternative, originate dai sistemi SYSV,
+come la XTI (\textit{X/Open Transport Interface}) nessuna ha mai raggiunto la
+diffusione e la popolarità di quella dei socket (e tantomeno usabilità e
+flessibilità).
+
+
+\section{Concetti base}
+\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
+problemi) siano diverse a seconda del tipo di protocollo di comunicazione
+usato, le funzioni da usare restano le stesse.
+
+Per questo motivo una semplice descrizione dell'interfaccia è assolutamente
+inutile, in quanto il comportamento di quest'ultima e le problematiche da
+affrontare cambiano radicalmente a seconda dello ``stile'' di comunicazione
+usato. La scelta di questo stile va infatti ad incidere sulla semantica che
+verrà utilizzata a livello utente per gestire la comunicazione (su come
+inviare e ricevere i dati) e sul comportamento effettivo delle funzioni
+utilizzate.
+
+La scelta di uno stile dipende sia dai meccanismi disponibili, sia dal tipo di
+comunicazione che si vuole effettuare. Ad esempio alcuni stili di
+comunicazione considerano i dati come una sequenza continua di bytes, altri
+invece li raggruppano in blocchi (i pacchetti).
+
+Un'altro esempio di stile concerne la possibilità che la comunicazione possa o
+meno perdere dati, possa o meno non rispettare l'ordine in cui essi non sono
+inviati, o inviare dei pacchetti più volte (come nel caso di TCP e UDP).
+
+Un terzo esempio di stile di comunicazione concerne le modalità in cui essa
+avviene, in certi casi essa può essere condotta con una connessione diretta
+con un solo partner come per una telefonata; altri casi possono prevedere una
+comunicazione come per lettera, in cui si scrive l'indirizzo su ogni
+pacchetto, altri ancora una comunicazione \textit{broadcast} come per la
+radio, in cui i pacchetti vengono emessi su appositi ``canali'' dove chiunque
+si collega possa riceverli.
+
+É chiaro che ciascuno di questi stili comporta una modalità diversa di gestire
+la comunicazione, ad esempio se è inaffidabile occorrerà essere in grado di
+gestire la perdita o il rimescolamento dei dati.
+
+Dati i tanti e diversi protocolli di comunicazione disponibili, esistono vari
+tipi di socket, che vengono classificati raggruppandoli in quelli che si
+chiamano \textsl{domini} (\textit{domains}). La scelta di un dominio equivale
+in sostanza alla scelta di una famiglia di protocolli. Ciascun dominio ha un
+suo nome simbolico che convenzionalmente inizia con \texttt{PF\_} (da
+\textit{protocol family}, altro nome con cui si indicano i domini).
+
+A ciascun tipo di dominio corrisponde un analogo nome simbolico che inizia per
+\texttt{AF\_} (da \textit{Address Family}, nome che useremo anche noi; le man
+pages di linux si riferiscono a questi anche come \textit{name space}, nome
+che però il manuale della glibc riserva ai domini) e che identifica il formato
+degli indirizzi usati in quel dominio.
+
+I domini (e i relativi nomi simbolici) sono definiti dall'header
+\textit{socket.h}. In linux sono disponibili le famiglie di protocolli
+riportate in \ntab.
+
+\begin{table}[htb]
+ \centering
+ \begin{tabular}[c]{lll}
+ Nome & Utilizzo & Man page \\
+ PF\_UNIX,PF\_LOCAL & Local communication & unix(7) \\
+ PF\_INET & IPv4 Internet protocols & ip(7) \\
+ PF\_INET6 & IPv6 Internet protocols & \\
+ PF\_IPX & IPX - Novell protocols & \\
+ PF\_NETLINK & Kernel user interface device & netlink(7) \\
+ PF\_X25 & ITU-T X.25 / ISO-8208 protocol & x25(7) \\
+ PF\_AX25 & Amateur radio AX.25 protocol & \\
+ PF\_ATMPVC & Access to raw ATM PVCs & \\
+ PF\_APPLETALK & Appletalk & ddp(7) \\
+ PF\_PACKET & Low level packet interface & packet(7) \\
+ \end{tabular}
+ \caption{Famiglie di protocolli definiti in linux}
+ \label{tab:net_pf_names}
+\end{table}
+
+
+La scelta di un dominio non comporta però la scelta dello stile di
+comunicazione, questo infatti viene a dipendere dal protocollo che si andrà ad
+utilizzare fra quelli disponibili nella famiglia scelta. Le API permettono di
+scegliere lo stile di comunicazione indicando il tipo di socket; linux e le
+glibc mettono a disposizione i seguenti tipi di socket (che il manuale della
+glibc chiama \textit{styles}) definiti come \texttt{int} in \texttt{socket.h}:
+
+\begin{list}{}{}
+\item \texttt{SOCK\_STREAM} Provvede un canale di trasmissione dati
+ bidirezionale, sequenziale e affidabile. Opera su una connessione con un
+ altro socket. I dati vengono ricevuti e trasmessi come un flusso continuo di
+ byte (da cui il nome \textit{stream}). Vedi \ref{sec:sock_stream}.
+\item \texttt{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza
+ massima fissata (\textit{datagram}) indirizzati singolarmente, senza
+ connessione e in maniera non affidabile. È l'opposto del precedente. Vedi
+ \ref{sec:sock_dgram}.
+\item \texttt{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati
+ bidirezionale, sequenziale e affidabile. Opera su una connessione con un
+ altro socket. I dati possono solo essere trasmessi e letti per pacchetti (di
+ dimensione massima fissata).
+\item \texttt{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di
+ rete e alle varie interfacce. I normali programmi di comunicazione non
+ devono usarlo.
+\item \texttt{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti
+ affidabile ma in cui non è garantito l'ordine di arrivo dei pacchetti.
+\item \texttt{SOCK\_PACKET} Obsoleto, non deve essere usato.
+\end{list}
+
+
+
+
+