From adbc2a4478d606025705a406603e6097584b9fa0 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Wed, 5 Mar 2003 00:45:30 +0000 Subject: [PATCH] Nuova vesione divisa in due parti. Completata la parte di IPC. Rivista la parte di reti. Iniziata la revisione della parte dei socket. Aggiunte le strutture degli indirizzi di AppleTalk e DECnet. --- elemtcp.tex | 5 +- gapil.tex | 1 + intro.tex | 4 + ipc.tex | 23 +-- network.tex | 239 ++++++++++++++----------- socket.tex | 420 +++++++++++++++++++++++++++----------------- sources/SharedMem.c | 5 +- 7 files changed, 421 insertions(+), 276 deletions(-) diff --git a/elemtcp.tex b/elemtcp.tex index 39fc7cd..6cf1129 100644 --- a/elemtcp.tex +++ b/elemtcp.tex @@ -741,10 +741,13 @@ Per questo motivo nell'header \file{netinet/in.h} \const{in6addr\_any} (dichiarata come \direct{extern}, ed inizializzata dal sistema al valore \const{IN6ADRR\_ANY\_INIT}) che permette di effettuare una assegnazione del tipo: - \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} serv_add.sin6_addr = in6addr_any; /* connect from anywhere */ \end{lstlisting} +in maniera analoga si può utilizzare la variabile \const{in6addr\_loopback} +per indicare l'indirizzo di \textit{loopback}, che a sua volta viene +inizializzata staticamente a \const{IN6ADRR\_LOOPBACK\_INIT}. + \subsection{La funzione \func{connect}} diff --git a/gapil.tex b/gapil.tex index 0193dc9..ab1bf2c 100644 --- a/gapil.tex +++ b/gapil.tex @@ -116,6 +116,7 @@ % distance from margins for boxedminipage %\fboxsep=6pt + \include{intro} \include{process} \include{prochand} diff --git a/intro.tex b/intro.tex index 04d7ad8..56c59ff 100644 --- a/intro.tex +++ b/intro.tex @@ -8,6 +8,10 @@ %% license is included in the section entitled "GNU Free Documentation %% License". %% +\part{Programmazione di sistema} +\label{part:progr-di-sist} + + \chapter{L'architettura del sistema} \label{cha:intro_unix} diff --git a/ipc.tex b/ipc.tex index 25274c9..7bd296f 100644 --- a/ipc.tex +++ b/ipc.tex @@ -4509,8 +4509,8 @@ mappati in memoria; questi verranno cancellati automaticamente dal sistema solo con le rispettive chiamate a \func{close} e \func{munmap}. Una volta eseguita questa funzione però, qualora si richieda l'apertura di un segmento con lo stesso nome, la chiamata a \func{shm\_open} fallirà, a meno di non aver -usato \const{O\_CREAT}, nel qual caso comunque si otterrà il riferimento ad un -segmento distinto dal precedente. +usato \const{O\_CREAT}, in quest'ultimo caso comunque si otterrà un file +descriptor che fa riferimento ad un segmento distinto da eventuali precedenti. \begin{figure}[!htb] \footnotesize \centering @@ -4559,8 +4559,7 @@ void * FindShm(char * shm_name, off_t shm_size) /* Function RemoveShm: Remove a POSIX shared memory segment */ int RemoveShm(char * shm_name) { - shm_unlink(shm_name); - return 0; + return shm_unlink(shm_name); } \end{lstlisting} \end{minipage} @@ -4570,16 +4569,17 @@ int RemoveShm(char * shm_name) \label{fig:ipc_posix_shmmem} \end{figure} -Come esempio di queste funzioni vediamo come è possibile riscrivere con esse -funzioni analoghe a quelle viste in \secref{fig:ipc_sysv_shm_func}; il codice, -riportato in \figref{fig:ipc_posix_shmmem}, è sempre contenuto nel file -\file{SharedMem.c} dei sorgenti allegati. +Come esempio per l'uso di queste funzioni vediamo come è possibile riscrivere +una interfaccia semplificata analoga a quella vista in +\secref{fig:ipc_sysv_shm_func} per la memoria condivisa in stile SysV. Il +codice, riportato in \figref{fig:ipc_posix_shmmem}, è sempre contenuto nel +file \file{SharedMem.c} dei sorgenti allegati. La prima funzione (\texttt{\small 1--24}) è \func{CreateShm} che, dato un nome nell'argomento \var{name} crea un nuovo segmento di memoria condivisa, accessibile in lettura e scrittura, e ne restituisce l'indirizzo. Anzitutto si definiscono (\texttt{\small 8}) i flag per la successiva (\texttt{\small 9}) -chiamata a \func{shm\_open} che apre il segmento in lettura e scrittura +chiamata a \func{shm\_open}, che apre il segmento in lettura e scrittura (creandolo se non esiste, ed uscendo in caso contrario) assegnandogli sul filesystem i permessi specificati dall'argomento \var{perm}. In caso di errore (\texttt{\small 10--12}) si restituisce un puntatore nullo, altrimenti si @@ -4603,11 +4603,12 @@ memoria con \func{mmap}, restituendo (\texttt{\small 36--38}) un puntatore nullo in caso di errore, o l'indirizzo (\texttt{\small 39}) dello stesso in caso di successo. -La terza funzione (\texttt{\small 40--46}) è \func{FindShm}, e serve a +La terza funzione (\texttt{\small 40--45}) è \func{RemoveShm}, e serve a cancellare un segmento di memoria condivisa. Dato che al contrario di quanto avveniva con i segmenti del SysV IPC gli oggetti allocati nel kernel vengono rilasciati automaticamente quando nessuna li usa più, tutto quello che c'è da -fare (\texttt{\small 45}) in questo caso è chiamare \func{shm\_unlink}. +fare (\texttt{\small 44}) in questo caso è chiamare \func{shm\_unlink}, +retituendo al chiamante il valore di ritorno. diff --git a/network.tex b/network.tex index e904ccf..606a330 100644 --- a/network.tex +++ b/network.tex @@ -8,6 +8,9 @@ %% license is included in the section entitled "GNU Free Documentation %% License". %% +\part{Programmazione di rete} +\label{part:progr-di-rete} + \chapter{Introduzione alla programmazione di rete} \label{cha:network} @@ -22,27 +25,40 @@ programmazione, ci concentreremo sul protocollo pi quello che sta alla base di internet, avendo cura di sottolineare i concetti più importanti da conoscere per la scrittura dei programmi. -\section{Il modello client-server} -\label{sec:net_cliserv} + + +\section{Modelli di programmazione} +\label{sec:net_prog_model} + La differenza principale fra un'applicazione di rete e un programma normale è che quest'ultima per definizione concerne la comunicazione fra processi -diversi (che in generale non girano neanche sulla stessa macchina). Questo già +diversi, che in generale non girano neanche sulla stessa macchina. Questo già prefigura un cambiamento completo rispetto all'ottica del programma monolitico all'interno del quale vengono eseguite tutte le istruzioni, e chiaramente -presuppone un sistema operativo multitasking in grado di eseguire processi -diversi. +presuppone un sistema operativo multitasking in grado di eseguire più processi +contemporaneamente. + +In questa prima sezione esamineremo brevemente i principali modelli di +programmazione in uso. Ne daremo una descrizione assolutamente generica e +superficiale, che ne illustri le caratteristiche principali, non essendo fra +gli scopi del testo approfondire questi argomenti. + +\subsection{Il modello \textit{client-server}} +\label{sec:net_cliserv} -Un concetto fondamentale su cui si basa la programmazione di rete sotto Linux +Il concetto fondamentale su cui si basa la programmazione di rete sotto Linux (e sotto Unix in generale) è il modello \textit{client-server} in cui un -programma di servizio, il \textit{server}, riceve una connessione e risponde a -un programma di utilizzo, il \textit{client}, provvedendo a quest'ultimo un -definito insieme di servizi. +programma di servizio, il \textit{server}, riceve una richiesta e risponde a +un programma di utilizzo, il \textit{client}, fornendo a quest'ultimo un +definito insieme di servizi. -Esempi di questo modello sono il WEB, ftp, telnet, ssh e praticamente ogni -servizio che viene fornito tramite la rete, ma il modello è utilizzato in -generale anche per programmi che non fanno necessariamente uso della rete, -come il sistema a finestre. +Infatti seguono questo modello tutti i servizi fondamentali di internet, come +il le pagine web, ftp, telnet, ssh e praticamente ogni servizio che viene +fornito tramite la rete, anche se, come abbiamo visto, il modello è utilizzato +in generale anche per programmi che, come gli esempi che abbiamo usato in +\capref{cha:IPC} a proposito della comunicazione fra processi nello stesso +sistema, non fanno necessariamente uso della rete. Normalmente si dividono i server in due categorie principali, e vengono detti \textsl{concorrenti} o \textsl{iterativi}, sulla base del loro comportamento. @@ -59,13 +75,23 @@ soddisfatte contemporaneamente; una volta che il processo figlio ha concluso il suo lavoro viene terminato, mentre il server originale resta sempre attivo. +\subsection{Il modello \textit{peer-to-perr}} +\label{sec:net_peertopeer} + +Da fare + +\subsection{Il modello \textit{three-tier}} +\label{sec:net_three_tier} + +Da fare + \section{I protocolli di rete} \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 +ottica, alle comunicazioni via satellite o via radio; 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 protocollo TCP/IP. @@ -74,13 +100,13 @@ del funzionamento di internet, \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 \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 quanto riportato in \tabref{tab:net_osilayers}. +in livelli sovrapposti; in questo modo ogni protocollo di un certo livello +realizza le sue funzionalità basandosi su un protocollo del livello +sottostante. 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 quanto riportato in +\tabref{tab:net_osilayers}. \begin{table}[htb] \centering @@ -102,14 +128,14 @@ livelli, secondo quanto riportato in \tabref{tab:net_osilayers}. \label{tab:net_osilayers} \end{table} -Il modello ISO/OSI è stato sviluppato in corrispondenza alla definizione -della serie di protocolli X.25 per la commutazione di pacchetto. Ma nonostante -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 (\textit{Department of - Defense}), dato che fu sviluppato dall'agenzia ARPA per il Dipartimento -della Difesa Americano. +Il modello ISO/OSI è stato sviluppato in corrispondenza alla definizione della +serie di protocolli X.25 per la commutazione di pacchetto. Ma nonostante il +lavoro dettagliato di standardizzazione il modello si è rivelato +sostanzialmente troppo complesso e poco flessibile rispetto a quello +precedente, il TCP/IP, su cui si basa internet, che è diventato uno standard +de facto. Il modello di quest'ultimo viene chiamato anche modello DoD (sigla +che sta per \textit{Department of Defense}), dato che fu sviluppato +dall'agenzia ARPA per il Dipartimento della Difesa Americano. \begin{figure}[!htbp] \centering @@ -120,15 +146,15 @@ della Difesa Americano. \end{figure} -\subsection{Il modello DoD (TCP/IP)} +\subsection{Il modello TCP/IP (o DoD)} \label{sec:net_tcpip_overview} -Così come ISO/OSI anche TCP/IP è stato strutturato in livelli (riassunti in -\tabref{tab:net_layers}); un confronto fra i due è riportato in +Così come ISO/OSI anche il modello del TCP/IP è stato strutturato in livelli +(riassunti in \tabref{tab:net_layers}); un confronto fra i due è riportato in \figref{fig:net_osi_tcpip_comp} dove viene evidenziata anche la corrispondenza fra i rispettivi livelli (che comunque è approssimativa) e su come essi vanno -ad inserirsi all'interno del sistema operativo rispetto alla divisione fra -user space e kernel space spiegata in \secref{sec:intro_unix_struct}. +ad inserirsi all'interno di un sistema rispetto alla divisione fra user space +e kernel space spiegata in \secref{sec:intro_unix_struct}. \begin{table}[htb] \centering @@ -137,11 +163,11 @@ user space e kernel space spiegata in \secref{sec:intro_unix_struct}. \textbf{Livello} & \multicolumn{2}{|c|}{\textbf{Nome}} & \textbf{Esempi} \\ \hline \hline - Livello 1&\textit{Application} &\textsl{Applicazione}& + Livello 4&\textit{Application} &\textsl{Applicazione}& Telnet, FTP, etc. \\ - Livello 2&\textit{Transport} &\textsl{Trasporto}& TCP, UDP \\ - Livello 3&\textit{Network} &\textsl{Rete}& IP, (ICMP, IGMP) \\ - Livello 4&\textit{Link} &\textsl{Connessione}& + Livello 3&\textit{Transport} &\textsl{Trasporto}& TCP, UDP \\ + Livello 2&\textit{Network} &\textsl{Rete}& IP, (ICMP, IGMP) \\ + Livello 1&\textit{Link} &\textsl{Connessione}& device driver \& scheda di interfaccia \\ \hline \end{tabular} @@ -149,19 +175,22 @@ user space e kernel space spiegata in \secref{sec:intro_unix_struct}. \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 -\textit{Internet Protocol}. Le funzioni dei vari livelli sono le seguenti: +Come si può notare come il modello TCP/IP è più semplice del modello ISO/OSI +ed è strutturato in soli quattro livelli. Il suo nome deriva dai due +principali protocolli che lo compongono, il TCP (\textit{Trasmission Control + Protocol}) che copre il livello 3 e l'IP (\textit{Internet Protocol}) che +copre il livello 2. Le funzioni dei vari livelli sono le seguenti: \begin{description} -\item \textbf{Applicazione} É relativo ai programmi di interfaccia utente, in - genere questi vengono realizzati secondo il modello client-server (vedi - \secref{sec:net_cliserv}. +\item \textbf{Applicazione} É relativo ai programmi di interfaccia con la + rete, in genere questi vengono realizzati secondo il modello client-server + (vedi \secref{sec:net_cliserv}), realizzando una comunicazione secondo un + protocollo che è specifico di ciascuna applicazione. \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 - errori. Il protocollo principale di questo livello è il TCP. + informazioni, può fornire un trasporto affidabile, cioè con recupero degli + errori o inaffidabile. I protocolli principali di questo livello sono il TCP + e l'UDP. \item \textbf{Rete} Si occupa dello smistamento dei singoli pacchetti su una rete complessa e interconnessa, a questo stesso livello operano i protocolli per il reperimento delle informazioni necessarie allo smistamento, per lo @@ -174,18 +203,21 @@ compongono, il TCP \textit{Trasmission Control Protocol} e l'IP \end{description} -La comunicazione fra due stazioni avviene secondo le modalità illustrate in -\figref{fig:net_tcpip_data_flux}, dove si è riportato il flusso dei dati reali -e i protocolli usati per lo scambio di informazione su ciascuno livello. +La comunicazione fra due stazioni remote avviene secondo le modalità +illustrate in \figref{fig:net_tcpip_data_flux}, dove si è riportato il flusso +dei dati reali e i protocolli usati per lo scambio di informazione su ciascun +livello. Si è genericamente indicato \textit{ethernet} per il livello 1, anche +se in realtà i protocolli di trasmissione usati possono essere molti altri. + \begin{figure}[!htb] - \centering - \includegraphics[width=10cm]{img/tcp_data_flux} + \centering \includegraphics[width=10cm]{img/tcp_data_flux} \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} -La struttura della comunicazione pertanto si può riassumere nei seguenti passi: +La struttura della comunicazione attraverso il TCP/IP si può pertanto +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 @@ -206,14 +238,14 @@ La struttura della comunicazione pertanto si pu \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). + comunicazione (ad esempio \textit{ethernet} per una scheda di rete). \end{itemize} -\subsection{Criteri generali del design di TCP/IP} +\subsection{Criteri generali dell'architettura del TCP/IP} \label{sec:net_tcpip_design} -La filosofia architetturale di TCP/IP è semplice: costruire una rete che +La filosofia architetturale del TCP/IP è semplice: costruire una rete che possa sopportare il carico in transito, ma permettere ai singoli nodi di scartare pacchetti se il carico è temporaneamente eccessivo, o se risultano errati o non recapitabili. @@ -257,9 +289,10 @@ socket\index{socket}, Questo avviene perché al di sopra del livello di trasporto i programmi hanno a che fare solo con dettagli specifici delle applicazioni, mentre al di sotto vengono curati tutti i dettagli relativi alla comunicazione. È pertanto -naturale definire una API su questo confine tanto più che è proprio li (come -evidenziato in \figref{fig:net_osi_tcpip_comp}) che nei sistemi Unix (e non -solo) viene inserita la divisione fra kernel space e user space. +naturale definire una interfaccia di programmazione su questo confine tanto +più che è proprio lì (come evidenziato in \figref{fig:net_osi_tcpip_comp}) che +nei sistemi Unix (e non solo) viene inserita la divisione fra kernel space e +user space. In realtà in un sistema Unix è possibile accedere anche agli altri livelli inferiori (e non solo a quello di trasporto) con opportune interfacce (la cosa @@ -268,10 +301,10 @@ TCP), ma queste vengono usate solo quando si vogliono fare applicazioni di sistema per il controllo della rete a basso livello, un uso quindi molto specialistico, e che non rientra in quanto trattato qui. -In questa sezione daremo una breve descrizione dei vari protocolli di TCP/IP, -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. +In questa sezione daremo una breve descrizione dei vari protocolli del TCP/IP, +concentrandoci, per le ragioni esposte sul livello di trasporto. All'interno +di questo privilegeremo poi il protocollo TCP, per il ruolo centrale che +svolge nella maggior parte delle applicazioni. \subsection{Il quadro generale} @@ -307,11 +340,11 @@ I vari protocolli mostrati in figura sono i seguenti: 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\index{socket} UDP sono esempi di - \textit{datagram socket}. Contrariamente al TCP in protocollo non è + connessione, a pacchetti. I socket\index{socket} UDP sono esempi di + \textit{datagram socket}. Contrariamente al TCP il 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. + destinazione, si perdano o vengano duplicati, o abbiano un particolare + 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{host} e \textit{router}). I messaggi sono normalmente @@ -331,17 +364,18 @@ I vari protocolli mostrati in figura sono i seguenti: 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. +\item \textsl{NETLINK} \textit{Netlink}. Provvede, in Linux, 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. +Gran parte delle applicazioni comunicano usando TCP o UDP, solo alcune, e per +scopi particolari si rifanno dirattamente 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} @@ -359,9 +393,9 @@ 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{Universal addressing} la comunicazione avviene fra due stazioni + remote identificate 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. @@ -380,21 +414,21 @@ 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 + nodi indirizzabili molto maggiore e una autoconfigurazione degli indirizzi. \item l'introduzione un nuovo tipo di indirizzamento, l'\textit{anycast} che - si aggiunge agli usuali \textit{unycast} e \textit{multicast} + si aggiunge agli usuali \textit{unycast} e \textit{multicast}. \item la semplificazione del formato dell'intestazione (\textit{header}) dei pacchetti, 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'ampliamento degli indirizzi + contenere l'aumento di dimensione dovuto all'ampliamento degli indirizzi. \item un supporto per le opzioni migliorato, per garantire una trasmissione più efficiente del traffico normale, limiti meno stringenti sulle dimensioni delle opzioni, e la flessibilità necessaria per introdurne di nuove in - futuro -\item il supporto per delle capacità di qualità di servizio (QoS) che + futuro. +\item il supporto per delle capacità di \textsl{qualità di servizio} (QoS) che permettano di identificare gruppi di dati per i quali si può provvedere un trattamento speciale (in vista dell'uso di internet per applicazioni - multimediali e/o ``real-time'') + multimediali e/o ``real-time''). \end{itemize} Maggiori dettagli riguardo a caratteristiche, notazioni e funzionamento del @@ -417,7 +451,7 @@ 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 -destinazione occorrerà provvedere con l'applicazione all'interno della quale +destinazione occorrerà provvedere con l'applicazione, all'interno della quale si dovrà inserire tutto quanto necessario a gestire la notifica di ricevimento, la ritrasmissione, il timeout. @@ -444,8 +478,9 @@ stessa frequenza. Nonostante gli evidenti svantaggi comportati dall'inaffidabilità UDP ha il grande pregio della velocità che in certi casi è essenziale; inoltre si presta bene per le applicazioni in cui la connessione non è necessaria e -costituirebbe solo un peso di prestazioni mentre una perdita di pacchetti può -essere tollerata, ad esempio quelle che usano il multicasting. +costituirebbe solo un peso in termini di prestazioni mentre una perdita di +pacchetti può essere tollerata, ad esempio le applicazioni di streaming e +quelle che usano il multicasting. \subsection{Transport Control Protocol (TCP)} \label{sec:net_tcp} @@ -490,17 +525,17 @@ all'arrivo sar 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 -essere ricevuti. +ricevere tramite una \textit{advertised window} (letteralmente +\textsl{finestra annunciata)}, che indica lo spazio disponibile nel buffer di +ricezione, 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 socket\index{socket} ed aumentando con la lettura di quest'ultimo da parte dell'applicazione, se diventa nulla il buffer di ricezione è pieno e non verranno accettati altri dati. Si noti che UDP non provvede niente di tutto ciò per cui nulla impedisce che vengano trasmessi pacchetti ad un rate che il -ricevitore non può sostenere. +ricevente non può sostenere. Infine attraverso TCP la trasmissione è sempre bidirezionale (in inglese \textit{full-duplex}), è cioè possibile sia trasmettere che ricevere allo @@ -514,16 +549,16 @@ Una descrizione pi \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 aspetto di cui bisogna tenere conto nella programmazione di rete, e che +ritornerà anche più avanti, è 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: +Un elenco di questi limiti, insieme ad un breve accenno alle loro origini ed +alle eventuali implicazioni che possono avere, è il seguente: \begin{itemize} -\item La dimensione massima di un pacchetti IP è di 65535 byte, compreso +\item La dimensione massima di un pacchetto IP è di 65535 byte, compreso l'header. Questo è dovuto al fatto che la dimensione è indicata da un campo apposito nell'header di IP che è lungo 16 bit (vedi \figref{fig:IP_ipv4_head}). @@ -591,7 +626,7 @@ di un pacchetto di dimensione eccessiva per la ritrasmissione generer 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 +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 diff --git a/socket.tex b/socket.tex index 2e34e78..5a2a8ea 100644 --- a/socket.tex +++ b/socket.tex @@ -11,15 +11,15 @@ \chapter{Introduzione ai socket} \label{cha:socket_intro} -In questo capitolo inizieremo a spiegare le caratteristiche principali della +In questo capitolo inizieremo a spiegare le caratteristiche salienti della principale interfaccia per la programmazione di rete, quella dei -\textit{socket}, che pur essendo nata in unix è usata ormai da tutti i sistemi -operativi. +\textit{socket}, che, pur essendo nata in ambiente Unix è usata ormai da tutti +i sistemi operativi. Dopo una breve panoramica sulle caratteristiche di questa interfaccia vedremo come creare un socket e come collegarlo allo specifico protocollo di rete che -utilizzerà per la comunicazione. Per evitare un'introduzione puramente teorica -concluderemo il capitolo con un primo esempio di applicazione. +si utilizzerà per la comunicazione. Per evitare un'introduzione puramente +teorica concluderemo il capitolo con un primo esempio di applicazione. \section{Una panoramica} \label{sec:sock_overview} @@ -33,30 +33,30 @@ con essi. \subsection{I \textit{socket}} \label{sec:sock_socket_def} -Il \textit{socket}\footnote{una traduzione letterale potrebbe essere +I \textit{socket}\footnote{una traduzione letterale potrebbe essere \textsl{presa}, ma essendo universalmente noti come socket utilizzeremo - sempre la parola inglese.} è uno dei principali meccanismi di comunicazione -fra programmi utilizzato in ambito Unix. 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 (vedi \secref{sec:ipc_pipes}) ma a -differenza di questa e degli altri meccanismi esaminati nel capitolo -\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 - 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 SVr4, -come la XTI (\textit{X/Open Transport Interface}) nessuna ha mai raggiunto la -diffusione e la popolarità di quella dei socket (né tantomeno la stessa -usabilità e flessibilità). - -La flessibilità e la genericità dell'interfaccia inoltre ha consentito di + sempre la parola inglese.} sono uno dei principali meccanismi di +comunicazione utilizzato in ambito Unix, e li abbiamo brevemente incontrati in +\secref{sec:ipc_socketpair}, fra i vari meccanismi di intercominazione fra +processi. Un 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 (vedi \secref{sec:ipc_pipes}) ma, a differenza di questa e degli altri +meccanismi esaminati nel capitolo \capref{cha:IPC}, i socket non sono limitati +alla comunicazione fra processi che girano sulla stessa macchina, ma possono +realizzare la comunicazione anche attraverso la rete. + +Quella dei socket costituisce infatti la principale interfaccia usata nella +programmazione di rete. La loro origine risale al 1983, quando furono +introdotti in BSD 4.2; l'interfaccia è rimasta sostanzialmente la stessa, con +piccole modifiche, negli anni successivi. Benché siano state sviluppate +interfacce alternative, originate dai sistemi SVr4 come la XTI (\textit{X/Open + Transport Interface}) nessuna ha mai raggiunto la diffusione e la popolarità +di quella dei socket (né tantomeno la stessa usabilità e flessibilità). + +La flessibilità e la genericità dell'interfaccia inoltre consente di utilizzare i socket con i più disparati meccanismi di comunicazione, e non -solo con la suite dei protocolli TCP/IP, che sarà comunque quella di cui -tratteremo in maniera più estesa. +solo con la suite dei protocolli TCP/IP, anche se questa sarà comunque quella +di cui tratteremo in maniera più estesa. \subsection{Concetti base} @@ -87,9 +87,9 @@ inviati, o inviare dei pacchetti pi 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 +con un solo corrispondente, 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 ``\textsl{canali}'' dove chiunque si collega possa riceverli. @@ -154,58 +154,88 @@ attraverso i quali si vuole effettuare la comunicazione. 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}. 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}, e che identifica il formato degli -indirizzi usati in quel dominio; le pagine di manuale di Linux si riferiscono -a questi anche come \textit{name space}, (nome che però il manuale delle -\acr{glibc} riserva ai domini) e che identifica il formato degli indirizzi -usati in quel dominio. - -L'idea alla base della distinzione era che una famiglia di protocolli potesse -supportare vari tipi di indirizzi, per cui il prefisso \texttt{PF\_} si -sarebbe dovuto usare nella creazione dei socket e il prefisso \texttt{AF\_} in -quello delle strutture degli indirizzi; questo è quanto specificato anche -dallo standard POSIX.1g, ma non esistono a tuttora famiglie di protocolli che -supportino diverse strutture di indirizzi, per cui nella pratica questi due -nomi sono equivalenti e corrispondono agli stessi valori. - -I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di -indirizzi sono definiti dall'header \textit{socket.h}. In Linux le famiglie di -protocolli disponibili sono riportate in \tabref{tab:net_pf_names}. +scelta di una famiglia di protocolli, e viene effettuata attraverso +l'argomento \param{domain} della funzione \func{socket}. Ciascun dominio ha un +suo nome simbolico che convenzionalmente inizia con una costante che inizia +per \texttt{PF\_}, iniziali di \textit{protocol family}, un altro nome con cui +si indicano i domini. + +A ciascun tipo di dominio corrisponde un analogo nome simbolico, anch'esso +associato ad una costante, che inizia invece per \texttt{AF\_} (da +\textit{address family}) che identifica il formato degli indirizzi usati in +quel dominio. Le pagine di manuale di Linux si riferiscono a questi indirizzi +anche come \textit{name space},\footnote{nome che invece il manuale delle + \acr{glibc} riserva a quello che noi abbiamo chiamato domini.} dato che +identificano il formato degli indirizzi usati in quel dominio per identificare +i capi della comunicazione. \begin{table}[htb] \footnotesize \centering - \begin{tabular}[c]{|l|l|l|} + \begin{tabular}[c]{|l|l|l|l|} \hline - \textbf{Nome} & \textbf{Utilizzo} &\textbf{Man page} \\ + \textbf{Nome}&\textbf{Valore}&\textbf{Utilizzo}&\textbf{Man page} \\ \hline \hline - \const{PF\_UNIX}, - \const{PF\_LOCAL} & Local communication & unix(7) \\ - \const{PF\_INET} & IPv4 Internet protocols & ip(7) \\ - \const{PF\_INET6} & IPv6 Internet protocols & ipv6(7) \\ - \const{PF\_IPX} & IPX - Novell protocols & \\ - \const{PF\_NETLINK}& Kernel user interface device & netlink(7) \\ - \const{PF\_X25} & ITU-T X.25 / ISO-8208 protocol & x25(7) \\ - \const{PF\_AX25} & Amateur radio AX.25 protocol & \\ - \const{PF\_ATMPVC} & Access to raw ATM PVCs & \\ - \const{PF\_APPLETALK}& Appletalk & ddp(7) \\ - \const{PF\_PACKET} & Low level packet interface & packet(7) \\ + \const{PF\_UNSPEC} & 0& Non specificato & \\ + \const{PF\_LOCAL} & 1& Local communication & unix(7) \\ + \const{PF\_UNIX}, \const{PF\_FILE}&1& & \\ + \const{PF\_INET} & 2& IPv4 Internet protocols & ip(7) \\ + \const{PF\_AX25} & 3& Amateur radio AX.25 protocol & \\ + \const{PF\_IPX} & 4& IPX - Novell protocols & \\ + \const{PF\_APPLETALK}& 5& Appletalk & ddp(7) \\ + \const{PF\_NETROM} & 6& Amateur radio NetROM & \\ + \const{PF\_BRIDGE} & 7& Multiprotocol bridge & \\ + \const{PF\_ATMPVC} & 8& Access to raw ATM PVCs & \\ + \const{PF\_X25} & 9& ITU-T X.25 / ISO-8208 protocol& x25(7) \\ + \const{PF\_INET6} &10& IPv6 Internet protocols & ipv6(7) \\ + \const{PF\_ROSE} &11& Amateur Radio X.25 PLP & \\ + \const{PF\_DECnet} &12& Reserved for DECnet project & \\ + \const{PF\_NETBEUI} &13& Reserved for 802.2LLC project & \\ + \const{PF\_SECURITY} &14& Security callback pseudo AF & \\ + \const{PF\_KEY} &15& PF\_KEY key management API & \\ + \const{PF\_NETLINK} &16& Kernel user interface device & netlink(7) \\ + \const{PF\_PACKET} &17& Low level packet interface & packet(7) \\ + \const{PF\_ASH} &18& Ash & \\ + \const{PF\_ECONET} &19& Acorn Econet & \\ + \const{PF\_ATMSVC} &20& ATM SVCs & \\ + \const{PF\_SNA} &22& Linux SNA Project & \\ + \const{PF\_IRDA} &23& IRDA sockets & \\ + \const{PF\_PPPOX} &24& PPPoX sockets & \\ + \const{PF\_WANPIPE} &25& Wanpipe API sockets & \\ + \const{PF\_BLUETOOTH}&31& Bluetooth sockets & \\ \hline \end{tabular} - \caption{Famiglie di protocolli definiti in Linux} + \caption{Famiglie di protocolli definiti in Linux.} \label{tab:net_pf_names} \end{table} -Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad -esempio in generale tutti i socket di tipo \const{SOCK\_RAW} possono essere -creati solo da processi che hanno i privilegi di root (cioè con user-ID -effettivo uguale a zero) o con la capability \texttt{CAP\_NET\_RAW}. +L'idea alla base della distinzione fra questi due insiemi di costanti era che +una famiglia di protocolli potesse supportare vari tipi di indirizzi, per cui +il prefisso \texttt{PF\_} si sarebbe dovuto usare nella creazione dei socket e +il prefisso \texttt{AF\_} in quello delle strutture degli indirizzi; questo è +quanto specificato anche dallo standard POSIX.1g, ma non esistono a tuttora +famiglie di protocolli che supportino diverse strutture di indirizzi, per cui +nella pratica questi due nomi sono equivalenti e corrispondono agli stessi +valori numerici.\footnote{in Linux, come si può verificare andando a guardare + il contenuto di \file{bits/socket.h} le costanti sono esattamente le stesse + e ciascuna \texttt{AF\_} è definita alla corrispondente \texttt{PF\_} e con + lo stesso nome.} + +I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di +indirizzi, sono definiti dall'header \textit{socket.h}. Un elenco delle +famiglie di protocolli disponibili in Linux è riportato in +\tabref{tab:net_pf_names}.\footnote{l'elenco indica tutti i protocolli + definiti; fra questi però saranno utilizzabili solo quelli per i quali si è + compilato il supporto nel kernel (o si sono caricati gli opportuni moduli), + viene definita anche una costante \const{PF\_MAX} che indica il valore + massimo associabile ad un dominio (nel caso 32).} + +Si tenga presente che non tutte le famiglie di protocolli sono utilizzabili +dall'utente generico, ad esempio in generale tutti i socket di tipo +\const{SOCK\_RAW} possono essere creati solo da processi che hanno i privilegi +di amministratore (cioè con user-ID effettivo uguale a zero) o dotati della +capability \texttt{CAP\_NET\_RAW}. \subsection{Il tipo, o stile} @@ -213,31 +243,32 @@ effettivo uguale a zero) o con la capability \texttt{CAP\_NET\_RAW}. 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 -\acr{glibc} mettono a disposizione i seguenti tipi di socket (che il manuale -della \acr{glibc} chiama \textit{styles}) definiti come \ctyp{int} in -\file{socket.h}: - -\begin{list}{}{} -\item \const{SOCK\_STREAM} Provvede un canale di trasmissione dati +utilizzare fra quelli disponibili nella famiglia scelta. L'interfaccia dei +socket permette di scegliere lo stile di comunicazione indicando il tipo di +socket con l'argomento \param{type} di \func{socket}. Linux mette a +disposizione vari tipi di socket (che corrispondono a quelli che il manuale +della \acr{glibc} \cite{glibc} chiama \textit{styles}) identificati dalle +seguenti costanti: + +\begin{basedescript}{\desclabelwidth{2.8cm}\desclabelstyle{\nextlinelabel}} +\item[\const{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}). -\item \const{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza + byte (da cui il nome \textit{stream}). +\item[\const{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. -\item \const{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati +\item[\const{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 \const{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di +\item[\const{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 \const{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti +\item[\const{SOCK\_RDM}] Provvede un canale di trasmissione di pacchetti affidabile ma in cui non è garantito l'ordine di arrivo dei pacchetti. -\item \const{SOCK\_PACKET} Obsoleto, non deve essere usato. -\end{list} +\item[\const{SOCK\_PACKET}] Obsoleto, non deve essere usato. +\end{basedescript} Si tenga presente che non tutte le combinazioni fra una famiglia di protocolli e un tipo di socket sono valide, in quanto non è detto che in una famiglia @@ -281,11 +312,10 @@ elencati. \end{table} In \secref{tab:sock_sock_valid_combinations} sono mostrate le combinazioni -valide possibili per le varie famiglie di protocolli. Per ogni combinazione -valida si è indicato il tipo di protocollo, o la parola \textsl{si} qualora -non il protocollo non abbia un nome definito, mentre si sono lasciate vuote le -caselle per le combinazioni non supportate. - +valide possibili per le principali famiglie di protocolli. Per ogni +combinazione valida si è indicato il tipo di protocollo, o la parola +\textsl{si} qualora non il protocollo non abbia un nome definito, mentre si +sono lasciate vuote le caselle per le combinazioni non supportate. \section{Le strutture degli indirizzi dei socket} @@ -297,15 +327,13 @@ indirizzo che identifichi i due capi della comunicazione. La funzione infatti si limita ad allocare nel kernel quanto necessario per poter poi realizzare la comunicazione. -Gli indirizzi vengono specificati attraverso apposite strutture che vengono -utilizzate dalle altre funzioni della API dei socket quando la comunicazione -viene effettivamente realizzata. - -Ogni famiglia di protocolli ha ovviamente una sua forma di indirizzamento e in -corrispondenza a questa una sua peculiare struttura degli indirizzi; i nomi di -tutte queste strutture iniziano per \var{sockaddr\_}, quelli propri di -ciascuna famiglia vengono identificati dal suffisso finale, aggiunto al nome -precedente. +Gli indirizzi infatti vengono specificati attraverso apposite strutture che +vengono utilizzate dalle altre funzioni della interfaccia dei socket, quando +la comunicazione viene effettivamente realizzata. Ogni famiglia di protocolli +ha ovviamente una sua forma di indirizzamento e in corrispondenza a questa una +sua peculiare struttura degli indirizzi; i nomi di tutte queste strutture +iniziano per \var{sockaddr\_}, quelli propri di ciascuna famiglia vengono +identificati dal suffisso finale, aggiunto al nome precedente. \subsection{La struttura generica} @@ -315,11 +343,11 @@ Le strutture degli indirizzi vengono sempre passate alle varie funzioni attraverso puntatori (cioè \textit{by reference}), ma le funzioni devono poter maneggiare puntatori a strutture relative a tutti gli indirizzi possibili nelle varie famiglie di protocolli; questo pone il problema di come passare -questi puntatori, il C ANSI risolve questo problema coi i puntatori generici -(i \ctyp{void *}), ma l'interfaccia dei socket è antecedente alla definizione -dello standard ANSI, e per questo nel 1982 fu scelto di definire una struttura -generica per gli indirizzi dei socket, \struct{sockaddr}, che si è riportata in -\figref{fig:sock_sa_gen_struct}. +questi puntatori, il C moderno risolve questo problema coi i puntatori +generici (i \ctyp{void *}), ma l'interfaccia dei socket è antecedente alla +definizione dello standard ANSI C, e per questo nel 1982 fu scelto di definire +una struttura generica per gli indirizzi dei socket, \struct{sockaddr}, che si +è riportata in \figref{fig:sock_sa_gen_struct}. \begin{figure}[!htb] \footnotesize \centering @@ -339,12 +367,13 @@ struct sockaddr { Tutte le funzioni dei socket che usano gli indirizzi sono definite usando nel prototipo un puntatore a questa struttura; per questo motivo quando si invocano dette funzioni passando l'indirizzo di un protocollo specifico -occorrerà eseguire un casting del relativo puntatore. +occorrerà eseguire una coversione (il \textit{casting}) del relativo +puntatore. I tipi di dati che compongono la struttura sono stabiliti dallo standard -POSIX.1g, riassunti in \tabref{tab:sock_data_types} con i rispettivi file di -include in cui sono definiti; la struttura è invece definita nell'include file -\file{sys/socket.h}. +POSIX.1g e li abbiamo riassunti in \tabref{tab:sock_data_types} con i +rispettivi file di include in cui sono definiti; la struttura è invece +definita nell'include file \file{sys/socket.h}. \begin{table}[!htb] \centering @@ -379,10 +408,10 @@ include in cui sono definiti; la struttura \end{table} In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro -aggiuntivo \code{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi -libri). Questo campo non verrebbe usato direttamente dal programmatore e non è -richiesto dallo standard POSIX.1g, in Linux pertanto non esiste. Il campo -\type{sa\_family\_t} era storicamente un \ctyp{unsigned short}. +aggiuntivo \code{uint8\_t sin\_len} (come riportato da R. Stevens in +\cite{UNP1}). Questo campo non verrebbe usato direttamente dal programmatore e +non è richiesto dallo standard POSIX.1g, in Linux pertanto non esiste. Il +campo \type{sa\_family\_t} era storicamente un \ctyp{unsigned short}. Dal punto di vista del programmatore l'unico uso di questa struttura è quello di fare da riferimento per il casting, per il kernel le cose sono un po' @@ -397,9 +426,9 @@ l'uso di questa struttura. \label{sec:sock_sa_ipv4} I socket di tipo \const{PF\_INET} vengono usati per la comunicazione -attraverso internet; la struttura per gli indirizzi per un socket internet -(IPv4) è definita come \struct{sockaddr\_in} nell'header file -\file{netinet/in.h} e secondo le pagine di manuale ha la forma mostrata in +attraverso internet; la struttura per gli indirizzi per un socket internet (se +si usa IPv4) è definita come \struct{sockaddr\_in} nell'header file +\file{netinet/in.h} ed ha la forma mostrata in \figref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g. \begin{figure}[!htb] @@ -429,19 +458,24 @@ superiore come TCP e UDP. Questa struttura per RAW che accedono direttamente al livello di IP, nel qual caso il numero della porta viene impostato al numero di protocollo. -Il membro \var{sin\_family} deve essere sempre impostato; \var{sin\_port} -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 (con user-ID -effettivo uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} -possono usare la funzione \func{bind} su queste porte. - -Il membro \var{sin\_addr} contiene l'indirizzo internet dell'altro capo -della comunicazione, e viene acceduto sia come struttura (un resto di una -implementazione precedente in cui questa era una \direct{union} usata per -accedere alle diverse classi di indirizzi) che come intero. - -Infine è da sottolineare che sia gli indirizzi che i numeri di porta devono +Il membro \var{sin\_family} deve essere sempre impostato a \const{AF\_INET}, +altrimenti si avrà un errore di \errcode{EINVAL}; il membro \var{sin\_port} +specifica il \textsl{numero di porta} (affronteremo in dettaglio in le +\textsl{porte} in \secref{sec:TCPel_port_num}). I numeri di porta sotto il +1024 sono chiamati \textsl{riservati} in quanto utilizzati da servizi standard +e soltanto processi con i privilegi di amministratore (con user-ID effettivo +uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} possono +usare la funzione \func{bind} (che vedremo in \secref{sec:TCPel_func_bind}) su +queste porte. + +Il membro \var{sin\_addr} contiene un indirizzo internet, e viene acceduto sia +come struttura (un resto di una implementazione precedente in cui questa era +una \direct{union} usata per accedere alle diverse classi di indirizzi) che +direttamente come intero. In \file{netinet/in.h} vengono definiti anche alcune +costanti per alcuni indirizzi speciali, che vedremo in +\tabref{tab:TCPel_ipv4_addr}. + +Infine occorre sottolineare che sia gli indirizzi che i numeri di porta devono 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 @@ -452,10 +486,11 @@ problema e le relative soluzioni). \subsection{La struttura degli indirizzi IPv6} \label{sec:sock_sa_ipv6} -Essendo IPv6 un'estensione di IPv4 i socket di tipo \const{PF\_INET6} sono +Essendo IPv6 un'estensione di IPv4, i socket di tipo \const{PF\_INET6} sono sostanzialmente identici ai precedenti; la parte in cui si trovano -praticamente tutte le differenze è quella della struttura degli indirizzi. La -struttura degli indirizzi è definita ancora in \file{netinet/in.h}. +praticamente tutte le differenze fra i due socket è quella della struttura +degli indirizzi; la sua definizione, presa da \file{netinet/in.h}, è riportata +in \figref{fig:sock_sa_ipv6_struct}. \begin{figure}[!htb] \footnotesize \centering @@ -479,21 +514,22 @@ struct in6_addr { \label{fig:sock_sa_ipv6_struct} \end{figure} -Il campo \var{sin6\_family} deve essere sempre impostato ad -\const{AF\_INET6}, il campo \var{sin6\_port} è analogo a quello di IPv4 e -segue le stesse regole; il campo \var{sin6\_flowinfo} è a sua volta diviso -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 \secref{sec:IP_ipv6head}) ed il loro uso è sperimentale. - -Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6, -infine il campo \var{sin6\_scope\_id} è un campo introdotto con il kernel -2.4 per gestire alcune operazioni riguardanti il multicasting. +Il campo \var{sin6\_family} deve essere sempre impostato ad \const{AF\_INET6}, +il campo \var{sin6\_port} è analogo a quello di IPv4 e segue le stesse regole; +il campo \var{sin6\_flowinfo} è a sua volta diviso 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 \secref{sec:IP_ipv6head}) ed il +loro uso è sperimentale. + +Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6, infine +il campo \var{sin6\_scope\_id} è un campo introdotto in Linux con il kernel +2.4, per gestire alcune operazioni riguardanti il multicasting. -Si noti che questa struttura è più grande di una \struct{sockaddr} generica, -quindi occorre stare attenti a non avere fatto assunzioni riguardo alla -possibilità di contenere i dati nelle dimensioni di quest'ultima. +Si noti che questa struttura è più grande della \struct{sockaddr} generica +vista in \figref{fig:sock_sa_gen_struct}, quindi occorre stare attenti a non +avere fatto assunzioni riguardo alla possibilità di contenere i dati nelle +dimensioni di quest'ultima. \subsection{La struttura degli indirizzi locali} @@ -523,13 +559,79 @@ struct sockaddr_un { \label{fig:sock_sa_local_struct} \end{figure} -In questo caso il campo \var{sun\_family} deve essere \const{AF\_UNIX}, -mentre il campo \var{sun\_path} deve specificare un indirizzo; questo ha -due forme un file (di tipo socket) nel filesystem o una stringa univoca -(tenuta in uno spazio di nomi astratto). Nel primo caso l'indirizzo viene -specificato come una stringa (terminata da uno zero) corrispondente al -pathname del file; nel secondo invece \var{sun\_path} inizia con uno zero -vengono usati i restanti byte come stringa (senza terminazione). +In questo caso il campo \var{sun\_family} deve essere \const{AF\_UNIX}, mentre +il campo \var{sun\_path} deve specificare un indirizzo; questo ha due forme: +un file (di tipo socket) nel filesystem o una stringa univoca (mantenuta in +uno spazio di nomi astratto). Nel primo caso l'indirizzo viene specificato +come una stringa (terminata da uno zero) corrispondente al pathname del file; +nel secondo invece \var{sun\_path} inizia con uno zero vengono usati i +restanti byte come stringa (senza terminazione). + + +\subsection{La struttura degli indirizzi AppleTalk} +\label{sec:sock_sa_appletalk} + +I socket di tipo \const{PF\_APPLETALK} sono usati dalla libreria +\file{netatalk} per implementare la comunicazione secondo il protocollo +AppleTalk, uno dei primi protocolli di rete usato nel mondo dei personal +computer, usato dalla Apple per connettere fra loro computer e stampanti. Il +kernel supporta solo due strati del protocollo, DDP e AARP, e di norma è +opportuno usare le funzioni di libreria, si tratta qui questo argomento +principalmente per mostrare l'uso di un protocollo alternativo. + +I socket AppleTalk permettono di usare il protocollo DDP, che è un protocollo +a pacchetto, di tipo \const{SOCK\_DGRAM}; l'argomento \param{protocol} di +\func{socket} deve essere nullo. È altresì possibile usare i socket raw +specificando un tipo \const{SOCK\_RAW}, nel qual caso l'unico valore valido +per \param{protocol} è \func{ATPROTO\_DDP}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} +struct sockaddr_atalk { + sa_family_t sat_family; /* address family */ + u_char sat_port; /* port */ + struct at_addr sat_addr; /* net/node */ +}; + +struct at_addr { + unsigned short s_net; + unsigned char s_node; +}; + \end{lstlisting} + \end{minipage} + \caption{La struttura degli indirizzi dei socket AppleTalk + \structd{sockaddr\_atalk}.} + \label{fig:sock_sa_atalk_struct} +\end{figure} + +Il campo \var{sut\_family} deve essere sempre \const{AF\_APPLETALK}, mentre il +campo \var{sun\_port} specifica la porta che identifica i vari servizi. Valori +inferiori a 129 sono usati per le \textsl{porte riservate}, e possono essere +usati solo da processi con i privilegi di amministratore o con la capability +\const{CAP\_NET\_BIND\_SERVICE}. L'indirizzo remoto è specificato nella +struttura \var{sun\_addr}, e deve essere in \textit{network order}; esso è +composto da un parte di rete data dal campo \var{s\_net}, che può assumere il +valore \const{AT\_ANYNET}, che indica una rete genrica e vale anche per +indicare la rete su cui si è, il singolo nodo è indicato da \var{s\_node}, e +può prendere il valore generico \const{AT\_ANYNODE} che indica anche il nodo +corrente, ed il valore \const{ATADDR\_BCAST} che indica tutti i nodi della +rete. + + + + + +\subsection{La struttura degli indirizzi DECnet} +\label{sec:sock_sa_decnet} + +I socket di tipo \const{PF\_DECnet} usano il protocollo DECnet, usato dai VAX +Digital sotto VMS quando ancora il TCP/IP non era diventato lo standard di +fatto. Il protocollo è un protocollo chiuso, ed il suo uso attuale è di +compatibilità con macchine che stanno comunque scomparendo. Lo si riporta solo +come esempio + % \subsection{Il passaggio delle strutture} @@ -569,12 +671,12 @@ utile anche in seguito. La rappresentazione di un numero binario in un computer può essere fatta in due modi, chiamati rispettivamente \textit{big endian} e \textit{little endian} a seconda di come i singoli bit vengono aggregati per formare le -variabili intere (in diretta corrispondenza a come sono poi in realtà cablati -sui bus interni del computer). +variabili intere (ed in genere in diretta corrispondenza a come sono poi in +realtà cablati sui bus interni del computer). Per capire meglio il problema si consideri un intero a 16 bit scritto in una locazione di memoria posta ad un certo indirizzo. I singoli bit possono essere -disposti un memoria in due modi, a partire dal più significativo o a partire +disposti un memoria in due modi: a partire dal più significativo o a partire dal meno significativo. Così nel primo caso si troverà il byte che contiene i bit più significativi all'indirizzo menzionato e il byte con i bit meno significativi nell'indirizzo successivo; questo ordinamento è detto @@ -586,8 +688,8 @@ La \textit{endianess}\index{endianess} di un computer dipende essenzialmente dalla architettura hardware usata; Intel e Digital usano il \textit{little endian}, Motorola, IBM, Sun (sostanzialmente tutti gli altri) usano il \textit{big endian}. Il formato della rete è anch'esso \textit{big endian}, -altri esempi sono quello del bus PCI, che è \textit{little endian}, o quello -del bus VME che è \textit{big endian}. +altri esempi di uso di questi formati sono quello del bus PCI, che è +\textit{little endian}, o quello del bus VME che è \textit{big endian}. Esistono poi anche dei processori che possono scegliere il tipo di formato all'avvio e alcuni che, come il PowerPC o l'Intel i860, possono pure passare @@ -603,7 +705,7 @@ Il problema connesso all'endianess\index{endianess} dei dati da un tipo di architettura all'altra i dati vengono interpretati in maniera diversa, e ad esempio nel caso dell'intero a 16 bit ci si ritroverà con i due byte in cui è suddiviso scambiati di posto, e ne sarà quindi -invertito l'ordine di lettura per cui, per riavere il valore originale +invertito l'ordine di lettura per cui, per riavere il valore originale, dovranno essere rovesciati. Per questo motivo si usano delle funzioni di conversione che servono a tener @@ -658,7 +760,7 @@ dei numeri IP che si usa normalmente. Le prime tre funzioni di manipolazione riguardano la conversione degli indirizzi IPv4 da una stringa in cui il numero di IP è espresso secondo la cosiddetta notazione \textit{dotted-decimal}, (cioè nella forma -\texttt{192.160.0.1}) al formato binario (direttamente in \textit{network +\texttt{192.168.0.1}) al formato binario (direttamente in \textit{network order}) e viceversa; in questo caso si usa la lettera \texttt{a} come mnemonico per indicare la stringa. Dette funzioni sono \funcd{inet\_addr}, \funcd{inet\_aton} e \funcd{inet\_ntoa}, ed i rispettivi prototipi sono: diff --git a/sources/SharedMem.c b/sources/SharedMem.c index d4a9b9d..7e5d554 100644 --- a/sources/SharedMem.c +++ b/sources/SharedMem.c @@ -26,7 +26,7 @@ * * Author: S. Piccardi * - * $Id: SharedMem.c,v 1.5 2003/02/26 21:37:36 piccardi Exp $ + * $Id: SharedMem.c,v 1.6 2003/03/05 00:45:30 piccardi Exp $ * ***************************************************************/ #include /* SysV IPC shared memory declarations */ @@ -199,6 +199,5 @@ void * FindShm(char * shm_name, off_t shm_size) */ int RemoveShm(char * shm_name) { - shm_unlink(shm_name); - return 0; + return shm_unlink(shm_name); } -- 2.30.2