Inizio opzioni socket IPv4
authorSimone Piccardi <piccardi@gnulinux.it>
Fri, 19 Jan 2018 09:25:49 +0000 (09:25 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Fri, 19 Jan 2018 09:25:49 +0000 (09:25 +0000)
sockctrl.tex

index a0512bff2ce96534f1f645ae276c1270701ed5cf..a1a4a65c0b7e8c645a332ff8e7859e3ec9b2c5e7 100644 (file)
@@ -2792,7 +2792,7 @@ attivando il relativo comportamento.
 
 
 \constbeg{SO\_REUSEADDR}
-\subsubsection{Le opzioni \const{SO\_REUSEADDR} e \const{SO\_REUSEADDR}}
+\subsubsection{Le opzioni \const{SO\_REUSEADDR} e \const{SO\_REUSEPORT}}
 
 La seconda opzione da approfondire è \constd{SO\_REUSEADDR}, che consente di
 eseguire \func{bind} su un socket anche quando la porta specificata è già in
@@ -2824,6 +2824,17 @@ sono terminati, dato che una connessione può restare attiva anche dopo la
 chiusura del socket, mantenendosi nello stato \texttt{TIME\_WAIT} (vedi
 sez.~\ref{sec:TCP_time_wait}).
 
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/sockbindopt.c}
+  \end{minipage}
+  \normalsize
+  \caption{Le sezioni della funzione \texttt{sockbindopt} modificate rispetto al
+    codice della precedente \texttt{sockbind}.} 
+  \label{fig:sockbindopt_code}
+\end{figure}
+
 Usando \const{SO\_REUSEADDR} fra la chiamata a \func{socket} e quella a
 \func{bind} si consente a quest'ultima di avere comunque successo anche se la
 connessione è attiva (o nello stato \texttt{TIME\_WAIT}). È bene però
@@ -2836,17 +2847,6 @@ remota,\footnote{perché ciò avvenga infatti non solo devono coincidere gli
 eventuali pacchetti rimasti intrappolati in una precedente connessione possano
 finire fra quelli di una nuova.
 
-\begin{figure}[!htbp]
-  \footnotesize \centering
-  \begin{minipage}[c]{\codesamplewidth}
-    \includecodesample{listati/sockbindopt.c}
-  \end{minipage}
-  \normalsize
-  \caption{Le sezioni della funzione \texttt{sockbindopt} modificate rispetto al
-    codice della precedente \texttt{sockbind}.} 
-  \label{fig:sockbindopt_code}
-\end{figure}
-
 Come esempio di uso di questa connessione abbiamo predisposto una nuova
 versione della funzione \texttt{sockbind} (vedi fig.~\ref{fig:sockbind_code})
 che consenta l'impostazione di questa opzione. La nuova funzione è
@@ -2891,7 +2891,7 @@ valore, per cui in tal caso la successiva chiamata (\texttt{\small 13--17}) a
 \func{setsockopt} attiverà l'opzione \const{SO\_REUSEADDR}.
 
 Il secondo caso in cui viene usata \const{SO\_REUSEADDR} è quando si ha una
-macchina cui sono assegnati diversi numeri IP (o come suol dirsi
+macchina cui sono assegnati diversi indirizzi IP (o come suol dirsi
 \textit{multi-homed}) e si vuole porre in ascolto sulla stessa porta un
 programma diverso (o una istanza diversa dello stesso programma) per indirizzi
 IP diversi. Si ricordi infatti che è sempre possibile indicare a \func{bind}
@@ -2924,28 +2924,31 @@ invocare \func{getsockname} una volta che si è completata la connessione.
 
 Infine il quarto caso è quello in cui si vuole effettivamente ottenere un
 \textit{completely duplicate binding}, quando cioè si vuole eseguire
-\func{bind} su un indirizzo ed una porta che sono già \textsl{legati} ad un
-altro socket.  Come detto normalmente questo non è possibile con TCP, e non ha
-senso per il traffico di rete in cui i pacchetti vengono scambiati
-direttamente fra due applicazioni; ma quando un sistema supporta il traffico
-in \textit{multicast}, allora ha senso che su una macchina i pacchetti
-provenienti dal traffico in \textit{multicast} possano essere ricevuti da più
-applicazioni o da diverse istanze della stessa applicazione.
-
-L'esempio classico di traffico in \textit{multicast} è quello di uno streaming
-di dati (audio, video, ecc.), l'uso del \textit{multicast} consente in tal
-caso di trasmettere un solo pacchetto, che potrà essere ricevuto da tutti i
-possibili destinatari (invece di inviarne un duplicato a ciascuno); in questo
-caso è perfettamente logico aspettarsi che sulla stessa macchina più utenti
-possano lanciare un programma che permetta loro di ricevere gli stessi dati.
-
-In questo caso utilizzando \const{SO\_REUSEADDR} si consente ad una
+\func{bind} su un indirizzo ed una porta che sono già ``\textsl{legati}'' ad
+un altro socket.  Come accennato questo con TCP non è possibile, ed ha anche
+poco senso pensare di mettere in ascolto due server sulla stessa porta. Se
+però si prende in considerazione il traffico in \textit{multicast}, diventa
+assolutamente normale che i pacchetti provenienti dal traffico in
+\textit{multicast} possano essere ricevuti da più applicazioni o da diverse
+istanze della stessa applicazione sulla stessa porte di un indirizzo di
+\textit{multicast}.
+
+Un esempio classico è quello di uno streaming di dati (audio, video, ecc.) in
+cui l'uso del \textit{multicast} consente di trasmettere un solo pacchetto da
+recapitare a tutti i possibili destinatari (invece di inviarne un duplicato a
+ciascuno); in questo caso è perfettamente logico aspettarsi che sulla stessa
+macchina più utenti possano lanciare un programma che permetta loro di
+ricevere gli stessi dati, e quindi effettuare un \textit{completely duplicate
+  binding}.
+
+In questo caso utilizzando \const{SO\_REUSEADDR} si può consentire ad una
 applicazione eseguire \func{bind} sulla stessa porta ed indirizzo usata da
-un'altra, così che anche essa possa ricevere gli stessi pacchetti; come detto
-la cosa non è possibile con i socket TCP, ma lo è per quelli UDP che è il
-protocollo normalmente in uso da parte di queste applicazioni. La regola è che
-quando si hanno più applicazioni che hanno eseguito \func{bind} sulla stessa
-porta, di tutti pacchetti destinati ad un indirizzo di \textit{broadcast} o di
+un'altra, così che anche essa possa ricevere gli stessi pacchetti. Come detto
+la cosa non è possibile con i socket TCP (per i quali il \textit{multicast}
+comunque non è applicabile), ma lo è per quelli UDP che è il protocollo
+normalmente in uso da parte di queste applicazioni. La regola è che quando si
+hanno più applicazioni che hanno eseguito \func{bind} sulla stessa porta, di
+tutti pacchetti destinati ad un indirizzo di \textit{broadcast} o di
 \textit{multicast} viene inviata una copia a ciascuna applicazione. Non è
 definito invece cosa accade qualora il pacchetto sia destinato ad un indirizzo
 normale (\textit{unicast}).
@@ -2955,49 +2958,38 @@ normale (\textit{unicast}).
 \constbeg{SO\_REUSEPORT}
 
 Esistono però dei casi, in particolare per l'uso di programmi
-\textit{multithreaded}, in cui può essere necessario un \textit{completely
-  duplicate binding} 
-
-L'opzione deve essere attivata sul socket prima di chiamare \func{bind} e
-richiede che tutti i processi che si mettono in ascolto sullo stesso indirizzo
-abbiano lo stesso \ids{UID} effettivo, per evitare che un altro utente possa
-ottenere il relativo traffico (eseguendo quello che viene definito in
-\textit{port hijacking}); l'opzione utilizza per \param{optval} un intero
+\textit{multithreaded}, in cui può servire un \textit{completely duplicate
+  binding} anche per delle ordinarie connessioni TCP.  Per supportare queste
+esigenze a partire dal kernel 3.9 è stata introdotta un'altra opzione,
+\const{SO\_REUSEPORT} (già presente in altri sistemi come BSD), che consente
+di eseguire il \textit{completely duplicate binding}, fintanto che essa venga
+specificata per tutti i socket interessati. Come per \const{SO\_REUSEADDR}
+sarà possibile usare l'opzione su un socket legato allo stesso indirizzo e
+porta solo se il programma che ha eseguito il primo \func{bind} ha impostato
+questa opzione.
+
+Nel caso di \const{SO\_REUSEPORT} oltre al fatto che l'opzione deve essere
+attivata sul socket prima di chiamare \func{bind} ed attiva su tutti i socket
+con \textit{completely duplicate binding}, è richiesto pure che tutti i
+processi che si mettono in ascolto sullo stesso indirizzo e porta abbiano lo
+stesso \ids{UID} effettivo, per evitare che un altro utente possa ottenere il
+relativo traffico (eseguendo quello che viene definito \textit{port hijacking}
+o \textit{port stealing}). L'opzione utilizza per \param{optval} un intero
 usato come valore logico.
 
-  L'opzione si usa sia per socket TCP che UDP, nel primo caso consente un uso
-  distribuito si \func{accept} in una applicazione \textit{multithreaded}
-  passando un diverso \textit{listening socket} ad ogni thread (cosa che
-  migliora le prestazioni rispetto all'approccio tradizionale di usare un
-  thread per usare \func{accept} e distribuire le connessioni o avere più
-  thread che competono per usare \func{accept} sul socket. Nel caso di UDP
-  l'opzione consente di distribuire meglio i pacchetti su più processi o
-  thread rispetto all'approccio tradizionale di far competere gli stessi per
-  l'accesso in ricezione al socket.
-
-  % TODO documentare SO_REUSEPORT introdotta con il kernel 3.9, vedi
-  % http://git.kernel.org/linus/c617f398edd4db2b8567a28e899a88f8f574798d TODO:
-  % in cosa differisce da REUSEADDR?
-
-
-  Essendo questo un caso particolare in alcuni sistemi (come BSD) è stata
-  introdotta una opzione ulteriore, \const{SO\_REUSEPORT} che richiede che
-  detta opzione sia specificata per tutti i socket per i quali si vuole
-  eseguire il \textit{completely duplicate binding}. Nel caso di Linux questa
-  opzione non esisteva fino al kernel 3.9, ma il comportamento di
-  \const{SO\_REUSEADDR} è analogo, sarà cioè possibile effettuare un
-  \textit{completely duplicate binding} ed ottenere il successo di \func{bind}
-  su un socket legato allo stesso indirizzo e porta solo se il programma che
-  ha eseguito per primo \func{bind} su di essi ha impostato questa opzione.
-
-  Questa restrizione permette di evitare parzialmente il cosiddetto
-  \textit{port stealing}, in cui un programma, usando \const{SO\_REUSEADDR},
-  può collegarsi ad una porta già in uso e ricevere i pacchetti destinati ad
-  un altro programma; con questa caratteristica ciò è possibile soltanto se il
-  primo programma a consentirlo, avendo usato fin dall'inizio
-  \const{SO\_REUSEADDR}. Con l'introduzione di \const{SO\_REUSEPORT} una
-  ulteriore protezione deriva dalla richiesta che tutti i processi che usano
-  questa opzione per un socket abbiano lo stesso \ids{UID} effettivo.
+L'opzione si usa sia per socket TCP che UDP, nel primo caso consente un uso
+distribuito di \func{accept} in una applicazione \textit{multithreaded}
+passando un diverso \textit{listening socket} ad ogni thread, cosa che
+migliora le prestazioni rispetto all'approccio tradizionale di usare un thread
+per usare \func{accept} e distribuire le connessioni agli altri o avere più
+thread che competono per usare \func{accept} sul socket. Nel caso di UDP
+l'opzione consente di distribuire meglio i pacchetti su più processi o thread,
+rispetto all'approccio tradizionale di far competere gli stessi per l'accesso
+in ricezione al socket.
+
+% TODO documentare SO_REUSEPORT introdotta con il kernel 3.9, vedi
+% http://git.kernel.org/linus/c617f398edd4db2b8567a28e899a88f8f574798d TODO:
+% in cosa differisce da REUSEADDR?
 
 \constend{SO\_REUSEPORT}
 \constend{SO\_REUSEADDR}
@@ -3113,170 +3105,119 @@ manuale, nel caso specifico la documentazione si può consultare con
     \hline
     \const{IP\_ADD\_MEMBERSHIP} &         &$\bullet$&   &\struct{ip\_mreqn}& 
       Si unisce a un gruppo di \textit{multicast}.\\
-    \const{IP\_ADD\_SOURCE\_MEMBERSHIP} & &$\bullet$&   &\struct{ip\_mreqn\_source}& 
+    \const{IP\_ADD\_SOURCE\_MEMBERSHIP} & &$\bullet$&   &\struct{ip\_mreq\_source}& 
       Si unisce a un gruppo di \textit{multicast} per una sorgente.\\
+    \const{IP\_BLOCK\_SOURCE} & &$\bullet$&   &\struct{ip\_mreq\_source}& 
+      Smette di ricevere dati di \textit{multicast} per una sorgente.\\
     \const{IP\_DROP\_MEMBERSHIP}&         &$\bullet$&   &\struct{ip\_mreqn}& 
       Si sgancia da un gruppo di \textit{multicast}.\\
+    \const{IP\_DROP\_SOURCE\_MEMBERSHIP}& &$\bullet$&   &\struct{ip\_mreq\_source}& 
+      Si sgancia da un gruppo di \textit{multicast} per una sorgente.\\
+    \const{IP\_FREEBIND}       &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita il \textit{binding} a un indirizzo IP non locale ancora non assegnato.\\
     \const{IP\_HDRINCL}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
       Passa l'intestazione di IP nei dati.\\
     \const{IP\_MINTTL}          &$\bullet$&$\bullet$&   &\texttt{int}& 
       Imposta il valore minimo del TTL per i pacchetti accettati.\\ 
+    \const{IP\_MSFILTER}        &$\bullet$&$\bullet$&   &\struct{ip\_msfilter}& 
+      Accesso completo all'interfaccia per il filtraggio delle sorgenti
+      \textit{multicast}.\\  
     \const{IP\_MTU}             &$\bullet$&         &         &\texttt{int}& 
       Legge il valore attuale della MTU.\\
     \const{IP\_MTU\_DISCOVER}   &$\bullet$&$\bullet$&         &\texttt{int}& 
       Imposta il \textit{Path MTU Discovery}.\\
+    \const{IP\_MULTICAST\_ALL}  &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Imposta l'interfaccia locale di un socket \textit{multicast}.\\ 
     \const{IP\_MULTICAST\_IF}   &         &$\bullet$&   &\struct{ip\_mreqn}& 
       Imposta l'interfaccia locale di un socket \textit{multicast}.\\ 
     \const{IP\_MULTICAST\_LOOP} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
       Controlla il reinvio a se stessi dei dati di \textit{multicast}.\\ 
     \const{IP\_MULTICAST\_TTL}  &$\bullet$&$\bullet$&         &\texttt{int}& 
       Imposta il TTL per i pacchetti \textit{multicast}.\\
+    \const{IP\_NODEFRAG}        &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+      Disabilita il riassemblaggio di pacchetti frammentati.\\
     \const{IP\_OPTIONS}         &$\bullet$&$\bullet$&&\texttt{void *}& %??? 
       Imposta o riceve le opzioni di IP.\\
     \const{IP\_PKTINFO}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-      Passa un messaggio di informazione.\\
+      Abilita i messaggi di informazione.\\
     \const{IP\_RECVERR}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-      Abilita la gestione degli errori.\\
+      Abilita i messaggi di errore affidabili.\\
     \const{IP\_RECVOPTS}        &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
       Passa un messaggio con le opzioni IP.\\
+    \const{IP\_RECVORIGSTADDR}  &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita i messaggi con l'indirizzo di destinazione originale.\\
     \const{IP\_RECVTOS}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
       Passa un messaggio col campo TOS.\\
     \const{IP\_RECVTTL}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-      Passa un messaggio col campo TTL.\\
+      Abilita i messaggi col campo TTL.\\
     \const{IP\_RETOPTS}         &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
-      Passa un messaggio con le opzioni IP non trattate.\\
+      Abilita i messaggi con le opzioni IP non trattate.\\
     \const{IP\_ROUTER\_ALERT}   &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
       Imposta l'opzione \textit{IP router alert} sui pacchetti.\\
     \const{IP\_TOS}             &$\bullet$&$\bullet$&         &\texttt{int}& 
       Imposta il valore del campo TOS.\\
+    \const{IP\_TRANSPARENT}     &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+      Abilita un \textit{proxing} trasparente sul socket.\\
     \const{IP\_TTL}             &$\bullet$&$\bullet$&         &\texttt{int}& 
       Imposta il valore del campo TTL.\\
+    \const{IP\_UNBLOCK\_SOURCE} & &$\bullet$&   &\struct{ip\_mreq\_source}& 
+      Ricomincia a ricevere dati di \textit{multicast} per una sorgente.\\
    \hline
   \end{tabular}
   \caption{Le opzioni disponibili al livello \const{SOL\_IP}.} 
   \label{tab:sock_opt_iplevel}
 \end{table}
 
-Se si vuole operare su queste opzioni generiche il livello
-da utilizzare è \const{SOL\_IP} (o l'equivalente \constd{IPPROTO\_IP}); si è
-riportato un elenco di queste opzioni in tab.~\ref{tab:sock_opt_iplevel}.  Le
-costanti indicanti le opzioni, e tutte le altre costanti ad esse collegate,
-sono definite in \headfiled{netinet/ip.h}, ed accessibili includendo detto
-file.
+Se si vuole operare su queste opzioni generiche il livello da utilizzare è
+\constd{IPPROTO\_IP} (o l'equivalente \const{SOL\_IP}); si è riportato un
+elenco di queste opzioni in tab.~\ref{tab:sock_opt_iplevel}.  Le costanti
+indicanti le opzioni, e tutte le altre costanti ad esse collegate, sono
+definite in \headfiled{netinet/ip.h}, ed accessibili includendo detto file.
 
 Le descrizioni riportate in tab.~\ref{tab:sock_opt_iplevel} sono estremamente
 succinte, una maggiore quantità di dettagli sulle varie opzioni è fornita nel
 seguente elenco:
 \begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}}
-
-
-\item[\constd{IP\_OPTIONS}] l'opzione permette di impostare o leggere le
-  opzioni del protocollo IP (si veda sez.~\ref{sec:IP_options}). L'opzione
-  prende come valore dell'argomento \param{optval} un puntatore ad un buffer
-  dove sono mantenute le opzioni, mentre \param{optlen} indica la dimensione
-  di quest'ultimo. Quando la si usa con \func{getsockopt} vengono lette le
-  opzioni IP utilizzate per la spedizione, quando la si usa con
-  \func{setsockopt} vengono impostate le opzioni specificate. L'uso di questa
-  opzione richiede una profonda conoscenza del funzionamento del protocollo,
-  torneremo in parte sull'argomento in sez.~\ref{sec:sock_IP_options}.
-
-
-\item[\constd{IP\_PKTINFO}] Quando abilitata l'opzione permette di ricevere
-  insieme ai pacchetti un messaggio ancillare (vedi
-  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_PKTINFO} contenente
-  una struttura \struct{pktinfo} (vedi fig.~\ref{fig:sock_pktinfo_struct}) che
-  mantiene una serie di informazioni riguardo i pacchetti in arrivo. In
-  particolare è possibile conoscere l'interfaccia su cui è stato ricevuto un
-  pacchetto (nel campo \var{ipi\_ifindex}),\footnote{in questo campo viene
-    restituito il valore numerico dell'indice dell'interfaccia,
-    sez.~\ref{sec:sock_ioctl_netdevice}.} l'indirizzo locale da esso
-  utilizzato (nel campo \var{ipi\_spec\_dst}) e l'indirizzo remoto dello
-  stesso (nel campo \var{ipi\_addr}).
+\item[\constd{IP\_ADD\_MEMBERSHIP}] L'opzione consente di unirsi ad gruppo di
+  \textit{multicast}, e può essere usata solo con \func{setsockopt}.
+  L'argomento \param{optval} in questo caso deve essere una struttura di tipo
+  \struct{ip\_mreqn}, illustrata in fig.~\ref{fig:ip_mreqn_struct}, che
+  permette di indicare, con il campo \var{imr\_multiaddr} l'indirizzo del
+  gruppo di \textit{multicast} a cui ci si vuole unire, con il campo
+  \var{imr\_address} l'indirizzo dell'interfaccia locale con cui unirsi al
+  gruppo di \textit{multicast} e con \var{imr\_ifindex} l'indice
+  dell'interfaccia da utilizzare (un valore nullo indica una interfaccia
+  qualunque).
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{0.80\textwidth}
-    \includestruct{listati/pktinfo.h}
+  \begin{minipage}[c]{0.70\textwidth}
+    \includestruct{listati/ip_mreqn.h}
   \end{minipage}
-  \caption{La struttura \structd{pktinfo} usata dall'opzione
-    \const{IP\_PKTINFO} per ricavare informazioni sui pacchetti di un socket
-    di tipo \const{SOCK\_DGRAM}.}
-  \label{fig:sock_pktinfo_struct}
+  \caption{La struttura \structd{ip\_mreqn} utilizzata dalle opzioni dei
+    socket per le operazioni concernenti l'appartenenza ai gruppi di
+    \textit{multicast}.}
+  \label{fig:ip_mreqn_struct}
 \end{figure}
 
+  Per compatibilità è possibile utilizzare anche un argomento di tipo
+  \struct{ip\_mreq}, una precedente versione di \struct{ip\_mreqn}, che
+  differisce da essa soltanto per l'assenza del campo \var{imr\_ifindex}.
 
-L'opzione è utilizzabile solo per socket di tipo \const{SOCK\_DGRAM}. Questa è
-una opzione introdotta con i kernel della serie 2.2.x, ed è specifica di
-Linux;\footnote{non dovrebbe pertanto essere utilizzata se si ha a cuore la
-  portabilità.} essa permette di sostituire le opzioni \const{IP\_RECVDSTADDR}
-e \const{IP\_RECVIF} presenti in altri Unix (la relativa informazione è quella
-ottenibile rispettivamente dai campi \var{ipi\_addr} e \var{ipi\_ifindex} di
-\struct{pktinfo}). 
-
-L'opzione prende per \param{optval} un intero usato come valore logico, che
-specifica soltanto se insieme al pacchetto deve anche essere inviato o
-ricevuto il messaggio \const{IP\_PKTINFO} (vedi
-sez.~\ref{sec:net_ancillary_data}); il messaggio stesso dovrà poi essere
-letto o scritto direttamente con \func{recvmsg} e \func{sendmsg} (vedi
-sez.~\ref{sec:net_sendmsg}).
-
-
-\item[\constd{IP\_RECVTOS}] Quando abilitata l'opzione permette di ricevere
-  insieme ai pacchetti un messaggio ancillare (vedi
-  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_TOS}, che contiene un
-  byte con il valore del campo \textit{Type of Service} dell'intestazione IP
-  del pacchetto stesso (vedi sez.~\ref{sec:IP_header}).  Prende per
-  \param{optval} un intero usato come valore logico.
-
-\item[\constd{IP\_RECVTTL}] Quando abilitata l'opzione permette di ricevere
-  insieme ai pacchetti un messaggio ancillare (vedi
-  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_RECVTTL}, contenente
-  un byte con il valore del campo \textit{Time to Live} dell'intestazione IP
-  (vedi sez.~\ref{sec:IP_header}).  L'opzione richiede per \param{optval} un
-  intero usato come valore logico. L'opzione non è supportata per socket di
-  tipo \const{SOCK\_STREAM}.
-
-\item[\constd{IP\_RECVOPTS}] Quando abilitata l'opzione permette di ricevere
-  insieme ai pacchetti un messaggio ancillare (vedi
-  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_OPTIONS}, contenente
-  le opzioni IP del protocollo (vedi sez.~\ref{sec:IP_options}). Le
-  intestazioni di instradamento e le altre opzioni sono già riempite con i
-  dati locali. L'opzione richiede per \param{optval} un intero usato come
-  valore logico.  L'opzione non è supportata per socket di tipo
-  \const{SOCK\_STREAM}.
 
-\item[\constd{IP\_RETOPTS}] Identica alla precedente \const{IP\_RECVOPTS}, ma
-  in questo caso restituisce i dati grezzi delle opzioni, senza che siano
-  riempiti i capi di instradamento e le marche temporali.  L'opzione richiede
-  per \param{optval} un intero usato come valore logico.  L'opzione non è
-  supportata per socket di tipo \const{SOCK\_STREAM}.
+\item[\constd{IP\_BLOCK\_SOURCE}] TODO 
 
-\item[\constd{IP\_TOS}] L'opzione consente di leggere o impostare il campo
-  \textit{Type of Service} dell'intestazione IP (per una trattazione più
-  dettagliata, che riporta anche i valori possibili e le relative costanti di
-  definizione si veda sez.~\ref{sec:IP_header}) che permette di indicare le
-  priorità dei pacchetti. Se impostato il valore verrà mantenuto per tutti i
-  pacchetti del socket; alcuni valori (quelli che aumentano la priorità)
-  richiedono i privilegi di amministrazione con la \textit{capability}
-  \const{CAP\_NET\_ADMIN}.
-
-  Il campo TOS è di 8 bit e l'opzione richiede per \param{optval} un intero
-  che ne contenga il valore. Sono definite anche alcune costanti che
-  definiscono alcuni valori standardizzati per il \textit{Type of Service},
-  riportate in tab.~\ref{tab:IP_TOS_values}, il valore di default usato da
-  Linux è \const{IPTOS\_LOWDELAY}, ma esso può essere modificato con le
-  funzionalità del cosiddetto \textit{Advanced Routing}. Si ricordi che la
-  priorità dei pacchetti può essere impostata anche in maniera indipendente
-  dal protocollo utilizzando l'opzione \const{SO\_PRIORITY} illustrata in
-  sez.~\ref{sec:sock_generic_options}.
+\item[\constd{IP\_DROP\_MEMBERSHIP}] Lascia un gruppo di \textit{multicast},
+  prende per \param{optval} la stessa struttura \struct{ip\_mreqn} (o
+  \struct{ip\_mreq}) usata anche per \const{IP\_ADD\_MEMBERSHIP}.
 
-\item[\constd{IP\_TTL}] L'opzione consente di leggere o impostare per tutti i
-  pacchetti associati al socket il campo \textit{Time to Live}
-  dell'intestazione IP che indica il numero massimo di \textit{hop} (passaggi
-  da un router ad un altro) restanti al paccheto (per una trattazione più
-  estesa si veda sez.~\ref{sec:IP_header}).  Il campo TTL è di 8 bit e
-  l'opzione richiede che \param{optval} sia un intero, che ne conterrà il
-  valore.
+\item[\constd{IP\_HDRINCL}] Se abilitata l'utente deve fornire lui stesso
+  l'intestazione IP in cima ai propri dati. L'opzione è valida soltanto per
+  socket di tipo \const{SOCK\_RAW}, e quando utilizzata eventuali valori
+  impostati con \const{IP\_OPTIONS}, \const{IP\_TOS} o \const{IP\_TTL} sono
+  ignorati. In ogni caso prima della spedizione alcuni campi
+  dell'intestazione vengono comunque modificati dal kernel, torneremo
+  sull'argomento in sez.~\ref{sec:socket_raw}
 
 \item[\constd{IP\_MINTTL}] L'opzione, introdotta con il kernel 2.6.34, imposta
   un valore minimo per il campo \textit{Time to Live} dei pacchetti associati
@@ -3296,26 +3237,27 @@ sez.~\ref{sec:net_sendmsg}).
     senza carico aggiuntivo sulla CPU (che altrimenti dovrebbe calcolare una
     checksum).}
 
-\item[\constd{IP\_HDRINCL}] Se abilitata l'utente deve fornire lui stesso
-  l'intestazione IP in cima ai propri dati. L'opzione è valida soltanto per
-  socket di tipo \const{SOCK\_RAW}, e quando utilizzata eventuali valori
-  impostati con \const{IP\_OPTIONS}, \const{IP\_TOS} o \const{IP\_TTL} sono
-  ignorati. In ogni caso prima della spedizione alcuni campi
-  dell'intestazione vengono comunque modificati dal kernel, torneremo
-  sull'argomento in sez.~\ref{sec:socket_raw}
+\itindbeg{Path~MTU}
+\item[\constd{IP\_MTU}] Permette di leggere il valore della \textit{Path MTU}
+  di percorso del socket.  L'opzione richiede per \param{optval} un intero che
+  conterrà il valore della \textit{Path MTU} in byte.  Questa è una opzione
+  introdotta con i kernel della serie 2.2.x, ed è specifica di Linux.
 
-\item[\constd{IP\_RECVERR}] Questa è una opzione introdotta con i kernel della
-  serie 2.2.x, ed è specifica di Linux. Essa permette di usufruire di un
-  meccanismo affidabile per ottenere un maggior numero di informazioni in caso
-  di errori. Se l'opzione è abilitata tutti gli errori generati su un socket
-  vengono memorizzati su una coda, dalla quale poi possono essere letti con
-  \func{recvmsg} (vedi sez.~\ref{sec:net_sendmsg}) come messaggi ancillari
-  (torneremo su questo in sez.~\ref{sec:net_ancillary_data}) di tipo
-  \const{IP\_RECVERR}.  L'opzione richiede per \param{optval} un intero usato
-  come valore logico e non è applicabile a socket di tipo
-  \const{SOCK\_STREAM}.
+  È tramite questa opzione che un programma può leggere, quando si è avuto un
+  errore di \errval{EMSGSIZE}, il valore della MTU corrente del socket. Si
+  tenga presente che per poter usare questa opzione, oltre ad avere abilitato
+  la scoperta della \textit{Path MTU}, occorre che il socket sia stato
+  esplicitamente connesso con \func{connect}. 
+
+  Ad esempio con i socket UDP si potrà ottenere una stima iniziale della
+  \textit{Path MTU} eseguendo prima una \func{connect} verso la destinazione,
+  e poi usando \func{getsockopt} con questa opzione. Si può anche avviare
+  esplicitamente il procedimento di scoperta inviando un pacchetto di grosse
+  dimensioni (che verrà scartato) e ripetendo l'invio coi dati aggiornati. Si
+  tenga infine conto che durante il procedimento i pacchetti iniziali possono
+  essere perduti, ed è compito dell'applicazione gestirne una eventuale
+  ritrasmissione.
 
-\itindbeg{Path~MTU}
 \item[\constd{IP\_MTU\_DISCOVER}] Questa è una opzione introdotta con i kernel
   della serie 2.2.x, ed è specifica di Linux.  L'opzione permette di scrivere
   o leggere le impostazioni della modalità usata per la determinazione della
@@ -3358,43 +3300,11 @@ sez.~\ref{sec:net_sendmsg}).
   della MTU con un errore di \errval{EMSGSIZE}.\footnote{in caso contrario la
     trasmissione del pacchetto sarebbe effettuata, ottenendo o un fallimento
     successivo della trasmissione, o la frammentazione dello stesso.}
-
-\item[\constd{IP\_MTU}] Permette di leggere il valore della \textit{Path MTU}
-  di percorso del socket.  L'opzione richiede per \param{optval} un intero che
-  conterrà il valore della \textit{Path MTU} in byte.  Questa è una opzione
-  introdotta con i kernel della serie 2.2.x, ed è specifica di Linux.
-
-  È tramite questa opzione che un programma può leggere, quando si è avuto un
-  errore di \errval{EMSGSIZE}, il valore della MTU corrente del socket. Si
-  tenga presente che per poter usare questa opzione, oltre ad avere abilitato
-  la scoperta della \textit{Path MTU}, occorre che il socket sia stato
-  esplicitamente connesso con \func{connect}. 
-
-  Ad esempio con i socket UDP si potrà ottenere una stima iniziale della
-  \textit{Path MTU} eseguendo prima una \func{connect} verso la destinazione,
-  e poi usando \func{getsockopt} con questa opzione. Si può anche avviare
-  esplicitamente il procedimento di scoperta inviando un pacchetto di grosse
-  dimensioni (che verrà scartato) e ripetendo l'invio coi dati aggiornati. Si
-  tenga infine conto che durante il procedimento i pacchetti iniziali possono
-  essere perduti, ed è compito dell'applicazione gestirne una eventuale
-  ritrasmissione.
-
 \itindend{Path~MTU}
 
-\item[\constd{IP\_ROUTER\_ALERT}] Questa è una opzione introdotta con i
-  kernel della serie 2.2.x, ed è specifica di Linux. Prende per
-  \param{optval} un intero usato come valore logico. Se abilitata
-  passa tutti i pacchetti con l'opzione \textit{IP Router Alert} (vedi
-  sez.~\ref{sec:IP_options}) che devono essere inoltrati al socket
-  corrente. Può essere usata soltanto per socket di tipo raw.
-
-\item[\constd{IP\_MULTICAST\_TTL}] L'opzione permette di impostare o leggere il
-  valore del campo TTL per i pacchetti \textit{multicast} in uscita associati
-  al socket. È importante che questo valore sia il più basso possibile, ed il
-  default è 1, che significa che i pacchetti non potranno uscire dalla rete
-  locale. Questa opzione consente ai programmi che lo richiedono di superare
-  questo limite.  L'opzione richiede per
-  \param{optval} un intero che conterrà il valore del TTL.
+\item[\constd{IP\_MULTICAST\_IF}] Imposta l'interfaccia locale per l'utilizzo
+  del \textit{multicast}, ed utilizza come \param{optval} le stesse strutture
+  \struct{ip\_mreqn} o \struct{ip\_mreq} delle due precedenti opzioni.
 
 \item[\constd{IP\_MULTICAST\_LOOP}] L'opzione consente di decidere se i dati
   che si inviano su un socket usato con il \textit{multicast} vengano ricevuti
@@ -3407,43 +3317,138 @@ sez.~\ref{sec:net_sendmsg}).
   disponibili in locale l'uso di questa opzione permette di disabilitare
   questo tipo di traffico.
 
-\item[\constd{IP\_ADD\_MEMBERSHIP}] L'opzione consente di unirsi ad gruppo di
-  \textit{multicast}, e può essere usata solo con \func{setsockopt}.
-  L'argomento \param{optval} in questo caso deve essere una struttura di tipo
-  \struct{ip\_mreqn}, illustrata in fig.~\ref{fig:ip_mreqn_struct}, che
-  permette di indicare, con il campo \var{imr\_multiaddr} l'indirizzo del
-  gruppo di \textit{multicast} a cui ci si vuole unire, con il campo
-  \var{imr\_address} l'indirizzo dell'interfaccia locale con cui unirsi al
-  gruppo di \textit{multicast} e con \var{imr\_ifindex} l'indice
-  dell'interfaccia da utilizzare (un valore nullo indica una interfaccia
-  qualunque).
+\item[\constd{IP\_MULTICAST\_TTL}] L'opzione permette di impostare o leggere il
+  valore del campo TTL per i pacchetti \textit{multicast} in uscita associati
+  al socket. È importante che questo valore sia il più basso possibile, ed il
+  default è 1, che significa che i pacchetti non potranno uscire dalla rete
+  locale. Questa opzione consente ai programmi che lo richiedono di superare
+  questo limite.  L'opzione richiede per
+  \param{optval} un intero che conterrà il valore del TTL.
+% TODO chiarire quale è la struttura \struct{ip\_mreq}
 
-  Per compatibilità è possibile utilizzare anche un argomento di tipo
-  \struct{ip\_mreq}, una precedente versione di \struct{ip\_mreqn}, che
-  differisce da essa soltanto per l'assenza del campo \var{imr\_ifindex}.
+\item[\constd{IP\_OPTIONS}] l'opzione permette di impostare o leggere le
+  opzioni del protocollo IP (si veda sez.~\ref{sec:IP_options}). L'opzione
+  prende come valore dell'argomento \param{optval} un puntatore ad un buffer
+  dove sono mantenute le opzioni, mentre \param{optlen} indica la dimensione
+  di quest'ultimo. Quando la si usa con \func{getsockopt} vengono lette le
+  opzioni IP utilizzate per la spedizione, quando la si usa con
+  \func{setsockopt} vengono impostate le opzioni specificate. L'uso di questa
+  opzione richiede una profonda conoscenza del funzionamento del protocollo,
+  torneremo in parte sull'argomento in sez.~\ref{sec:sock_IP_options}.
+
+\item[\constd{IP\_PKTINFO}] Quando abilitata l'opzione permette di ricevere
+  insieme ai pacchetti un messaggio ancillare (vedi
+  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_PKTINFO} contenente
+  una struttura \struct{pktinfo} (vedi fig.~\ref{fig:sock_pktinfo_struct}) che
+  mantiene una serie di informazioni riguardo i pacchetti in arrivo. In
+  particolare è possibile conoscere l'interfaccia su cui è stato ricevuto un
+  pacchetto (nel campo \var{ipi\_ifindex}),\footnote{in questo campo viene
+    restituito il valore numerico dell'indice dell'interfaccia,
+    sez.~\ref{sec:sock_ioctl_netdevice}.} l'indirizzo locale da esso
+  utilizzato (nel campo \var{ipi\_spec\_dst}) e l'indirizzo remoto dello
+  stesso (nel campo \var{ipi\_addr}).
 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{0.80\textwidth}
-    \includestruct{listati/ip_mreqn.h}
+    \includestruct{listati/pktinfo.h}
   \end{minipage}
-  \caption{La struttura \structd{ip\_mreqn} utilizzata dalle opzioni dei
-    socket per le operazioni concernenti l'appartenenza ai gruppi di
-    \textit{multicast}.}
-  \label{fig:ip_mreqn_struct}
+  \caption{La struttura \structd{pktinfo} usata dall'opzione
+    \const{IP\_PKTINFO} per ricavare informazioni sui pacchetti di un socket
+    di tipo \const{SOCK\_DGRAM}.}
+  \label{fig:sock_pktinfo_struct}
 \end{figure}
 
-\item[\constd{IP\_DROP\_MEMBERSHIP}] Lascia un gruppo di \textit{multicast},
-  prende per \param{optval} la stessa struttura \struct{ip\_mreqn} (o
-  \struct{ip\_mreq}) usata anche per \const{IP\_ADD\_MEMBERSHIP}.
 
-\item[\constd{IP\_MULTICAST\_IF}] Imposta l'interfaccia locale per l'utilizzo
-  del \textit{multicast}, ed utilizza come \param{optval} le stesse strutture
-  \struct{ip\_mreqn} o \struct{ip\_mreq} delle due precedenti opzioni.
+L'opzione è utilizzabile solo per socket di tipo \const{SOCK\_DGRAM}. Questa è
+una opzione introdotta con i kernel della serie 2.2.x, ed è specifica di
+Linux;\footnote{non dovrebbe pertanto essere utilizzata se si ha a cuore la
+  portabilità.} essa permette di sostituire le opzioni \const{IP\_RECVDSTADDR}
+e \const{IP\_RECVIF} presenti in altri Unix (la relativa informazione è quella
+ottenibile rispettivamente dai campi \var{ipi\_addr} e \var{ipi\_ifindex} di
+\struct{pktinfo}). 
 
-% TODO chiarire quale è la struttura \struct{ip\_mreq}
+L'opzione prende per \param{optval} un intero usato come valore logico, che
+specifica soltanto se insieme al pacchetto deve anche essere inviato o
+ricevuto il messaggio \const{IP\_PKTINFO} (vedi
+sez.~\ref{sec:net_ancillary_data}); il messaggio stesso dovrà poi essere
+letto o scritto direttamente con \func{recvmsg} e \func{sendmsg} (vedi
+sez.~\ref{sec:net_sendmsg}).
+
+\item[\constd{IP\_RECVERR}] Questa è una opzione introdotta con i kernel della
+  serie 2.2.x, ed è specifica di Linux. Essa permette di usufruire di un
+  meccanismo affidabile per ottenere un maggior numero di informazioni in caso
+  di errori. Se l'opzione è abilitata tutti gli errori generati su un socket
+  vengono memorizzati su una coda, dalla quale poi possono essere letti con
+  \func{recvmsg} (vedi sez.~\ref{sec:net_sendmsg}) come messaggi ancillari
+  (torneremo su questo in sez.~\ref{sec:net_ancillary_data}) di tipo
+  \const{IP\_RECVERR}.  L'opzione richiede per \param{optval} un intero usato
+  come valore logico e non è applicabile a socket di tipo
+  \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RECVOPTS}] Quando abilitata l'opzione permette di ricevere
+  insieme ai pacchetti un messaggio ancillare (vedi
+  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_OPTIONS}, contenente
+  le opzioni IP del protocollo (vedi sez.~\ref{sec:IP_options}). Le
+  intestazioni di instradamento e le altre opzioni sono già riempite con i
+  dati locali. L'opzione richiede per \param{optval} un intero usato come
+  valore logico.  L'opzione non è supportata per socket di tipo
+  \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RECVTOS}] Quando abilitata l'opzione permette di ricevere
+  insieme ai pacchetti un messaggio ancillare (vedi
+  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_TOS}, che contiene un
+  byte con il valore del campo \textit{Type of Service} dell'intestazione IP
+  del pacchetto stesso (vedi sez.~\ref{sec:IP_header}).  Prende per
+  \param{optval} un intero usato come valore logico.
 
+\item[\constd{IP\_RECVTTL}] Quando abilitata l'opzione permette di ricevere
+  insieme ai pacchetti un messaggio ancillare (vedi
+  sez.~\ref{sec:net_ancillary_data}) di tipo \const{IP\_RECVTTL}, contenente
+  un byte con il valore del campo \textit{Time to Live} dell'intestazione IP
+  (vedi sez.~\ref{sec:IP_header}).  L'opzione richiede per \param{optval} un
+  intero usato come valore logico. L'opzione non è supportata per socket di
+  tipo \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_RETOPTS}] Identica alla precedente \const{IP\_RECVOPTS}, ma
+  in questo caso restituisce i dati grezzi delle opzioni, senza che siano
+  riempiti i capi di instradamento e le marche temporali.  L'opzione richiede
+  per \param{optval} un intero usato come valore logico.  L'opzione non è
+  supportata per socket di tipo \const{SOCK\_STREAM}.
+
+\item[\constd{IP\_ROUTER\_ALERT}] Questa è una opzione introdotta con i
+  kernel della serie 2.2.x, ed è specifica di Linux. Prende per
+  \param{optval} un intero usato come valore logico. Se abilitata
+  passa tutti i pacchetti con l'opzione \textit{IP Router Alert} (vedi
+  sez.~\ref{sec:IP_options}) che devono essere inoltrati al socket
+  corrente. Può essere usata soltanto per socket di tipo raw.
+
+\item[\constd{IP\_TOS}] L'opzione consente di leggere o impostare il campo
+  \textit{Type of Service} dell'intestazione IP (per una trattazione più
+  dettagliata, che riporta anche i valori possibili e le relative costanti di
+  definizione si veda sez.~\ref{sec:IP_header}) che permette di indicare le
+  priorità dei pacchetti. Se impostato il valore verrà mantenuto per tutti i
+  pacchetti del socket; alcuni valori (quelli che aumentano la priorità)
+  richiedono i privilegi di amministrazione con la \textit{capability}
+  \const{CAP\_NET\_ADMIN}.
 
+  Il campo TOS è di 8 bit e l'opzione richiede per \param{optval} un intero
+  che ne contenga il valore. Sono definite anche alcune costanti che
+  definiscono alcuni valori standardizzati per il \textit{Type of Service},
+  riportate in tab.~\ref{tab:IP_TOS_values}, il valore di default usato da
+  Linux è \const{IPTOS\_LOWDELAY}, ma esso può essere modificato con le
+  funzionalità del cosiddetto \textit{Advanced Routing}. Si ricordi che la
+  priorità dei pacchetti può essere impostata anche in maniera indipendente
+  dal protocollo utilizzando l'opzione \const{SO\_PRIORITY} illustrata in
+  sez.~\ref{sec:sock_generic_options}.
+
+\item[\constd{IP\_TTL}] L'opzione consente di leggere o impostare per tutti i
+  pacchetti associati al socket il campo \textit{Time to Live}
+  dell'intestazione IP che indica il numero massimo di \textit{hop} (passaggi
+  da un router ad un altro) restanti al paccheto (per una trattazione più
+  estesa si veda sez.~\ref{sec:IP_header}).  Il campo TTL è di 8 bit e
+  l'opzione richiede che \param{optval} sia un intero, che ne conterrà il
+  valore.
 \end{basedescript}