%% socket.tex
%%
-%% Copyright (C) 2000-2003 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2004 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Prefazione",
\textsl{presa}, ma essendo universalmente noti come \textit{socket}
utilizzeremo 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.
+in sez.~\ref{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 sez.~\ref{sec:ipc_pipes}) ma, a differenza di questa e degli altri
+meccanismi esaminati nel capitolo cap.~\ref{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
\label{sec:sock_gen}
Per capire il funzionamento dei socket occorre avere presente il funzionamento
-dei protocolli di rete (vedi \capref{cha:network}), ma l'interfaccia è del
+dei protocolli di rete (vedi cap.~\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.
La creazione di un socket avviene attraverso l'uso della funzione
\funcd{socket}; essa restituisce un \textit{file descriptor}\footnote{del
tutto analogo a quelli che si ottengono per i file di dati e le pipe,
- descritti in \secref{sec:file_fd}.} che serve come riferimento al socket; il
-suo prototipo è:
+ descritti in sez.~\ref{sec:file_fd}.} che serve come riferimento al socket;
+il suo prototipo è:
\begin{prototype}{sys/socket.h}{int socket(int domain, int type, int protocol)}
Apre un socket.
\end{prototype}
La funzione ha tre argomenti, \param{domain} specifica il dominio del socket
-(definisce cioè, come vedremo in \secref{sec:sock_domain}, la famiglia di
+(definisce cioè, come vedremo in sez.~\ref{sec:sock_domain}, la famiglia di
protocolli usata), \param{type} specifica il tipo di socket (definisce cioè,
-come vedremo in \secref{sec:sock_type}, lo stile di comunicazione) e
+come vedremo in sez.~\ref{sec:sock_type}, lo stile di comunicazione) e
\param{protocol} il protocollo; in genere quest'ultimo è indicato
implicitamente dal tipo di socket, per cui di norma questo valore viene messo
a zero (con l'eccezione dei \textit{raw socket}).
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
+indirizzi, sono definiti dall'header \texttt{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
+tab.~\ref{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
della \acr{glibc} \cite{glibc} chiama \textit{styles}) identificati dalle
seguenti costanti:
-\begin{basedescript}{\desclabelwidth{2.8cm}\desclabelstyle{\nextlinelabel}}
+\begin{basedescript}{\desclabelwidth{2.9cm}\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
\label{tab:sock_sock_valid_combinations}
\end{table}
-In \secref{tab:sock_sock_valid_combinations} sono mostrate le combinazioni
+In tab.~\ref{tab:sock_sock_valid_combinations} sono mostrate le combinazioni
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
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}.
+è riportata in fig.~\ref{fig:sock_sa_gen_struct}.
\begin{figure}[!htb]
\footnotesize \centering
occorrerà eseguire una conversione del relativo puntatore.
I tipi di dati che compongono la struttura sono stabiliti dallo standard
-POSIX.1g e li abbiamo riassunti in \tabref{tab:sock_data_types} con i
+POSIX.1g e li abbiamo riassunti in tab.~\ref{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}.
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.
+fig.~\ref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g.
\begin{figure}[!htb]
\footnotesize\centering
L'indirizzo di un socket internet (secondo IPv4) comprende l'indirizzo
internet di un'interfaccia più un \textsl{numero di porta} (affronteremo in
-dettaglio il significato di questi numeri in \secref{sec:TCP_port_num}). Il
+dettaglio il significato di questi numeri in sez.~\ref{sec:TCP_port_num}). Il
protocollo IP non prevede numeri di porta, che sono utilizzati solo dai
protocolli di livello superiore come TCP e UDP. Questa struttura però viene
usata anche per i socket RAW che accedono direttamente al livello di IP, nel
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:TCP_func_bind}) su
+usare la funzione \func{bind} (che vedremo in sez.~\ref{sec:TCP_func_bind}) su
queste porte.
Il membro \var{sin\_addr} contiene un indirizzo internet, e viene acceduto sia
una \direct{union} usata per accedere alle diverse classi di indirizzi) che
direttamente come intero. In \file{netinet/in.h} vengono definite anche alcune
costanti che identificano alcuni indirizzi speciali, riportati in
-\tabref{tab:TCP_ipv4_addr}.
+tab.~\ref{tab:TCP_ipv4_addr}, che reincontreremo più avanti.
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
-portabilità del codice (vedi \secref{sec:sock_addr_func} per i dettagli del
+portabilità del codice (vedi sez.~\ref{sec:sock_addr_func} per i dettagli del
problema e le relative soluzioni).
sostanzialmente identici ai precedenti; la parte in cui si trovano
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}.
+in fig.~\ref{fig:sock_sa_ipv6_struct}.
\begin{figure}[!htb]
\footnotesize \centering
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.
+specifici dell'header dei pacchetti IPv6 (vedi sez.~\ref{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 ha una dimensione maggiore della struttura
-\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.
+Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
+espresso da un vettore di 16 byte. 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 infine che \struct{sockaddr\_in6} ha una
+dimensione maggiore della struttura \struct{sockaddr} generica di
+fig.~\ref{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}
vengono chiamati \textit{local domain} o anche \textit{Unix domain}); essi
hanno la caratteristica ulteriore di poter essere creati anche in maniera
anonima attraverso la funzione \func{socketpair} (che abbiamo trattato in
-\secref{sec:ipc_socketpair}). Quando però si vuole fare riferimento esplicito
-ad uno di questi socket si deve usare una struttura degli indirizzi di tipo
-\struct{sockaddr\_un}, la cui definizione si è riportata in
-\secref{fig:sock_sa_local_struct}.
+sez.~\ref{sec:ipc_socketpair}). Quando però si vuole fare riferimento
+esplicito ad uno di questi socket si deve usare una struttura degli indirizzi
+di tipo \struct{sockaddr\_un}, la cui definizione si è riportata in
+fig.~\ref{fig:sock_sa_local_struct}.
\begin{figure}[!htb]
\footnotesize \centering
Gli indirizzi AppleTalk devono essere specificati tramite una struttura
\struct{sockaddr\_atalk}, la cui definizione è riportata in
-\figref{fig:sock_sa_atalk_struct}; la struttura viene dichiarata includendo il
-file \file{netatalk/at.h}.
+fig.~\ref{fig:sock_sa_atalk_struct}; la struttura viene dichiarata includendo
+il file \file{netatalk/at.h}.
\begin{figure}[!htb]
\footnotesize \centering
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{sat\_addr}, e deve essere in \textit{network order} (vedi
-\secref{sec:sock_endianess}); esso è composto da un parte di rete data dal
+sez.~\ref{sec:sock_endianess}); 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 generica e vale anche per indicare la rete su cui si è, il singolo
nodo è indicato da \var{s\_node}, e può prendere il valore generico
Nel caso dei \textit{packet socket} la struttura degli indirizzi è di tipo
\struct{sockaddr\_ll}, e la sua definizione è riportata in
-\figref{fig:sock_sa_packet_struct}; essa però viene ad assumere un ruolo
+fig.~\ref{fig:sock_sa_packet_struct}; essa però viene ad assumere un ruolo
leggermente diverso rispetto a quanto visto finora per gli altri tipi di
socket. Infatti se il socket è di tipo \const{SOCK\_RAW} si deve comunque
scrivere tutto direttamente nel pacchetto, quindi la struttura non serve più a
Per capire meglio il problema si consideri un intero a 32 bit scritto in una
locazione di memoria posta ad un certo indirizzo. Come illustrato in
-\figref{fig:sock_endianess} i singoli bit possono essere disposti un memoria
+fig.~\ref{fig:sock_endianess} i singoli bit possono essere 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
Per controllare quale tipo di ordinamento si ha sul proprio computer si è
scritta una piccola funzione di controllo, il cui codice è riportato
-\figref{fig:sock_endian_code}, che restituisce un valore nullo (falso) se
+fig.~\ref{fig:sock_endian_code}, che restituisce un valore nullo (falso) se
l'architettura è \textit{big endian} ed uno non nullo (vero) se l'architettura
è \textit{little endian}.
Per questo prima (\texttt{\small 10}) si definisce il puntatore \var{ptr} per
accedere al contenuto della prima variabile, ed infine calcola (\texttt{\small
11}) il valore della seconda assumendo che il primo byte sia quello meno
-significativo (cioè, per quanto visto in \secref{fig:sock_endianess}, che sia
+significativo (cioè, per quanto visto in fig.~\ref{fig:sock_endianess}, che sia
\textit{little endian}). Infine la funzione restituisce (\texttt{\small 12})
il valore del confonto delle due variabili.
La funzione \func{inet\_aton} converte la stringa puntata da \param{src}
nell'indirizzo binario che viene memorizzato nell'opportuna struttura
-\struct{in\_addr} (si veda \secref{fig:sock_sa_ipv4_struct}) situata
+\struct{in\_addr} (si veda fig.~\ref{fig:sock_sa_ipv4_struct}) situata
all'indirizzo dato dall'argomento \param{dest} (è espressa in questa forma in
modo da poterla usare direttamente con il puntatore usato per passare la
struttura degli indirizzi). La funzione restituisce 0 in caso di successo e 1
Il formato usato per gli indirizzi in formato di presentazione è la notazione
\textit{dotted decimal} per IPv4 e quello descritto in
-\secref{sec:IP_ipv6_notation} per IPv6.
+sez.~\ref{sec:IP_ipv6_notation} per IPv6.
\index{socket|)}