From: Simone Piccardi Date: Fri, 19 Jan 2018 09:25:49 +0000 (+0000) Subject: Inizio opzioni socket IPv4 X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=7f3cd637082c70095a9f4f8873e4ec6400b670c0 Inizio opzioni socket IPv4 --- diff --git a/sockctrl.tex b/sockctrl.tex index a0512bf..a1a4a65 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -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}