\label{sec:sock_options}
Benché dal punto di vista del loro uso come canali di trasmissione di dati i
-socket vengano trattati allo stesso modo dei file, siano acceduti tramite i
-file descriptor, e gestiti con le ordinarie funzioni di lettura e scrittura
-dei file, l'interfaccia standard usata per la gestione dei file generici non è
-comunque sufficiente a poterne controllare tutte le caratteristiche
-specifiche, considerato poi che queste variano a seconda del tipo di socket (e
-della relativa forma di comunicazione sottostante).
+socket vengano trattati allo stesso modo dei file, acceduti tramite i file
+descriptor, e gestiti con le ordinarie funzioni di lettura e scrittura dei
+file, l'interfaccia standard usata per la gestione dei file generici non è
+comunque sufficiente a controllare la moltitudine di caratteristiche
+specifiche che li contraddistinguono, considerato tra l'altro che queste
+possono essere completamente diverse fra loro a seconda del tipo di socket e
+della relativa forma di comunicazione sottostante.
In questa sezione vedremo allora quali sono le funzioni dedicate alla gestione
-delle caratteristiche specifiche dei vari tipi di socket, le cosiddette
-\textit{socket options}, ma soprattutto analizzaremo quali sono queste opzioni
-e quali caretteristiche e comportamenti dei socket permettono di controllare.
+delle caratteristiche specifiche dei vari tipi di socket, che vengono
+raggruppate sotto il nome generico di ``\textit{socket options}'', ma
+soprattutto analizzaremo quali sono queste opzioni e quali caretteristiche e
+comportamenti dei socket permettono di controllare.
\subsection{Le funzioni di gestione delle opzioni dei socket}
\label{sec:sock_setsockopt}
-Le varie caratteristiche dei socket possono essere gestite attraverso l'uso di
-due funzioni generiche che permettono rispettivamente di impostarle e di
-recuperarne il valore corrente. La prima di queste due funzioni, quella usata
-per impostare le \textit{socket options}, è \funcd{setsockopt}, ed il suo
-prototipo è:
+La modalità principale con cui si possono gestire le caratteristiche dei
+socket (ne vedremo delle ulteriori nelle prossime sezioni) è quella che passa
+attraverso l'uso di due funzioni di sistema generiche che permettono
+rispettivamente di impostarle e di recuperarne il valore corrente. La prima di
+queste due funzioni, quella usata per impostare le \textit{socket options}, è
+\funcd{setsockopt}, ed il suo prototipo è:
\begin{funcproto}{
\fhead{sys/socket.h}
\const{SOL\_SOCKET} usato per le opzioni generiche che sono disponibili per
qualunque tipo di socket.
-I valori usati per \param{level}, corrispondenti ad un dato protocollo usato
-da un socket, sono quelli corrispondenti al valore numerico che identifica il
-suddetto protocollo in \conffile{/etc/protocols}; dato che la leggibilità di un
-programma non trarrebbe certo beneficio dall'uso diretto dei valori numerici,
-più comunemente si indica il protocollo tramite le apposite costanti
-\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels}, dove si sono
-riassunti i valori che possono essere usati per l'argomento
-\param{level}.\footnote{la notazione in questo caso è, purtroppo, abbastanza
- confusa: infatti in Linux il valore si può impostare sia usando le costanti
- \texttt{SOL\_*}, che le analoghe \texttt{IPPROTO\_*} (citate anche da
- Stevens in \cite{UNP1}); entrambe hanno gli stessi valori che sono
- equivalenti ai numeri di protocollo di \conffile{/etc/protocols}, con una
- eccezione specifica, che è quella del protocollo ICMP, per la quale non
- esista una costante, il che è comprensibile dato che il suo valore, 1, è
- quello che viene assegnato a \const{SOL\_SOCKET}.}
-
\begin{table}[!htb]
\centering
\footnotesize
\label{tab:sock_option_levels}
\end{table}
+I valori usati per \param{level}, corrispondenti ad un dato protocollo usato
+da un socket, sono quelli corrispondenti al valore numerico che identifica il
+suddetto protocollo in \conffile{/etc/protocols}; dato che la leggibilità di un
+programma non trarrebbe certo beneficio dall'uso diretto dei valori numerici,
+più comunemente si indica il protocollo tramite le apposite costanti
+\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels}, dove si sono
+riassunti i valori che possono essere usati per l'argomento
+\param{level}.
+
+La notazione in questo caso è, purtroppo, abbastanza confusa: infatti in Linux
+il valore si può impostare sia usando le costanti \texttt{SOL\_*}, che le
+analoghe \texttt{IPPROTO\_*} (citate anche da Stevens in \cite{UNP1});
+entrambe hanno gli stessi valori che sono equivalenti ai numeri di protocollo
+di \conffile{/etc/protocols}, con una eccezione specifica, che è quella del
+protocollo ICMP, per la quale non esiste una costante, il che è comprensibile
+dato che il suo valore, 1, è quello che viene assegnato a \const{SOL\_SOCKET}.
+
Il quarto argomento, \param{optval} è un puntatore ad una zona di memoria che
contiene i dati che specificano il valore dell'opzione che si vuole passare al
socket, mentre l'ultimo argomento \param{optlen},\footnote{questo argomento è
La seconda funzione usata per controllare le proprietà dei socket è
\funcd{getsockopt}, che serve a leggere i valori delle opzioni dei socket ed a
farsi restituire i dati relativi al loro funzionamento; il suo prototipo è:
-\begin{functions}
- \headdecl{sys/socket.h}
- \headdecl{sys/types.h}
- \funcdecl{int getsockopt(int s, int level, int optname, void *optval,
- socklen\_t *optlen)} Legge le opzioni di un socket.
- \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
- errore, nel qual caso \var{errno} assumerà i valori:
+\begin{funcproto}{
+\fhead{sys/socket.h}
+\fhead{sys/types.h}
+\fdecl{int getsockopt(int s, int level, int optname, void *optval,
+ socklen\_t *optlen)}
+\fdesc{Legge le opzioni di un socket.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
\begin{errlist}
\item[\errcode{EBADF}] il file descriptor \param{sock} non è valido.
\item[\errcode{EFAULT}] l'indirizzo \param{optval} o quello di
un socket.
\end{errlist}
}
-\end{functions}
+\end{funcproto}
I primi tre argomenti sono identici ed hanno lo stesso significato di quelli
di \func{setsockopt}, anche se non è detto che tutte le opzioni siano definite
\label{sec:sock_generic_options}
Come accennato esiste un insieme generico di opzioni dei socket che possono
-applicarsi a qualunque tipo di socket,\footnote{una descrizione di queste
- opzioni è generalmente disponibile nella settima sezione delle pagine di
- manuale, nel caso specifico la si può consultare con \texttt{man 7 socket}.}
-indipendentemente da quale protocollo venga poi utilizzato. Se si vuole
-operare su queste opzioni generiche il livello da utilizzare è
-\const{SOL\_SOCKET}; si è riportato un elenco di queste opzioni in
-tab.~\ref{tab:sock_opt_socklevel}.
+applicarsi a qualunque tipo di socket, indipendentemente da quale protocollo
+venga poi utilizzato. Una descrizione di queste opzioni è generalmente
+disponibile nella settima sezione delle pagine di manuale; nel caso specifico
+la si può consultare con \texttt{man 7 socket}. Se si vuole operare su queste
+opzioni generiche il livello da utilizzare è \const{SOL\_SOCKET}; si è
+riportato un elenco di queste opzioni in tab.~\ref{tab:sock_opt_socklevel}.
\begin{table}[!htb]
\textbf{Descrizione}\\
\hline
\hline
+ \const{SO\_ACCEPTCONN}&$\bullet$& & &\texttt{int}&
+ Indica se il socket è in ascolto.\\
+ \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$& &\texttt{char *}&
+ Lega il socket ad un dispositivo.\\
+ \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Attiva o disattiva il \textit{broadcast}.\\
+ \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita la compatibilità con BSD.\\
+ \const{SO\_BUSY\_POLL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Attiva il ``\textit{busy poll}'' sul socket.\\
+ \const{SO\_DEBUG} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita il debugging sul socket.\\
+ \const{SO\_DOMAIN} &$\bullet$& & &\texttt{int}&
+ Legge il tipo di socket.\\
+ \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Non invia attraverso un gateway.\\
+ \const{SO\_ERROR} &$\bullet$& & &\texttt{int}&
+ Riceve e cancella gli errori pendenti.\\
\const{SO\_KEEPALIVE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Controlla l'attività della connessione.\\
+ \const{SO\_LINGER} &$\bullet$&$\bullet$& &\texttt{linger}&
+ Indugia nella chiusura con dati da spedire.\\
+ \const{SO\_MARK} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta un ``\textit{firewall mark}'' sul socket.\\
\const{SO\_OOBINLINE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Lascia in linea i dati \textit{out-of-band}.\\
- \const{SO\_RCVLOWAT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Basso livello sul buffer di ricezione.\\
- \const{SO\_SNDLOWAT} &$\bullet$&$\bullet$& &\texttt{int}&
- Basso livello sul buffer di trasmissione.\\
- \const{SO\_RCVTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
- Timeout in ricezione.\\
- \const{SO\_SNDTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
- Timeout in trasmissione.\\
- \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Abilita la compatibilità con BSD.\\
\const{SO\_PASSCRED} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Abilita la ricezione di credenziali.\\
+ \const{SO\_PEEK\_OFF} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Imposta il valore del ``\textit{peek offset}''.\\
\const{SO\_PEERCRED} &$\bullet$& & &\texttt{ucred}&
Restituisce le credenziali del processo remoto.\\
- \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$& &\texttt{char *}&
- Lega il socket ad un dispositivo.\\
- \const{SO\_DEBUG} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Abilita il debugging sul socket.\\
+ \const{SO\_PRIORITY} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta la priorità del socket.\\
+ \const{SO\_PROTOCOL} &$\bullet$& & &\texttt{int}&
+ Ottiene il protocollo usato dal socket.\\
+ \const{SO\_RCVBUF} &$\bullet$&$\bullet$& &\texttt{int}&
+ Imposta dimensione del buffer di ricezione.\\
+ \const{SO\_RCVBUFFORCE}&$\bullet$&$\bullet$& &\texttt{int}&
+ Forza dimensione del buffer di ricezione.\\
+ \const{SO\_RCVLOWAT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Basso livello sul buffer di ricezione.\\
+ \const{SO\_RCVTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
+ Timeout in ricezione.\\
\const{SO\_REUSEADDR}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Consente il riutilizzo di un indirizzo locale.\\
- \const{SO\_TYPE} &$\bullet$& & &\texttt{int}&
- Restituisce il tipo di socket.\\
- \const{SO\_ACCEPTCONN}&$\bullet$& & &\texttt{int}&
- Indica se il socket è in ascolto.\\
- \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Non invia attraverso un gateway.\\
- \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Attiva o disattiva il \textit{broadcast}.\\
+ \const{SO\_REUSEPORT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Consente il riutilizzo di una porta.\\
+ \const{SO\_RXQ\_OVFL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Richiede messaggio ancillare con pacchetti persi.\\
\const{SO\_SNDBUF} &$\bullet$&$\bullet$& &\texttt{int}&
Imposta dimensione del buffer di trasmissione.\\
- \const{SO\_RCVBUF} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta dimensione del buffer di ricezione.\\
- \const{SO\_LINGER} &$\bullet$&$\bullet$& &\texttt{linger}&
- Indugia nella chiusura con dati da spedire.\\
- \const{SO\_PRIORITY} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta la priorità del socket.\\
- \const{SO\_ERROR} &$\bullet$& & &\texttt{int}&
- Riceve e cancella gli errori pendenti.\\
+ \const{SO\_SNDBUFFORCE}&$\bullet$&$\bullet$& &\texttt{int}&
+ Forza dimensione del buffer di trasmissione.\\
+ \const{SO\_SNDLOWAT} &$\bullet$&$\bullet$& &\texttt{int}&
+ Basso livello sul buffer di trasmissione.\\
+ \const{SO\_SNDTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}&
+ Timeout in trasmissione.\\
+ \const{SO\_TIMESTAMP}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita/disabilita la ricezione dei \textit{timestamp}.\\
+ \const{SO\_TYPE} &$\bullet$& & &\texttt{int}&
+ Restituisce il tipo di socket.\\
\hline
\end{tabular}
\caption{Le opzioni disponibili al livello \const{SOL\_SOCKET}.}
% TODO aggiungere e documentare SO_ATTACH_BPF, introdotta con il kernel 3.19,
% vedi http://lwn.net/Articles/625224/
% TODO aggiungere e documentare SO_INCOMING_CPU, introdotta con il kernel 3.19,
-% vedi https://lwn.net/Articles/626150/
+
La tabella elenca le costanti che identificano le singole opzioni da usare
come valore per \param{optname}; le due colonne seguenti indicano per quali
delle due funzioni (\func{getsockopt} o \func{setsockopt}) l'opzione è
-disponibile, mentre la colonna successiva indica, quando di ha a che fare con
+disponibile, mentre la colonna successiva indica, quando si ha a che fare con
un valore di \param{optval} intero, se l'opzione è da considerare un numero o
un valore logico. Si è inoltre riportato sulla quinta colonna il tipo di dato
usato per \param{optval} ed una breve descrizione del significato delle
separatamente in sez.~\ref{sec:sock_options_main}. Quello che segue è quindi
soltanto un elenco più dettagliato della breve descrizione di
tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
-\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
-
-\item[\const{SO\_KEEPALIVE}] questa opzione abilita un meccanismo di verifica
- della persistenza di una connessione associata al socket (ed è pertanto
- effettiva solo sui socket che supportano le connessioni, ed è usata
- principalmente con il TCP). L'opzione utilizza per \param{optval} un intero
- usato come valore logico. Maggiori dettagli sul suo funzionamento sono
- forniti in sez.~\ref{sec:sock_options_main}.
-
-\item[\constd{SO\_OOBINLINE}] se questa opzione viene abilitata i dati
- \textit{out-of-band} vengono inviati direttamente nel flusso di dati del
- socket (e sono quindi letti con una normale \func{read}) invece che restare
- disponibili solo per l'accesso con l'uso del flag \const{MSG\_OOB} di
- \func{recvmsg}. L'argomento è trattato in dettaglio in
- sez.~\ref{sec:TCP_urgent_data}. L'opzione funziona soltanto con socket che
- supportino i dati \textit{out-of-band} (non ha senso per socket UDP ad
- esempio), ed utilizza per \param{optval} un intero usato come valore logico.
-
-\item[\constd{SO\_RCVLOWAT}] questa opzione imposta il valore che indica il
- numero minimo di byte che devono essere presenti nel buffer di ricezione
- perché il kernel passi i dati all'utente, restituendoli ad una \func{read} o
- segnalando ad una \func{select} (vedi sez.~\ref{sec:TCP_sock_select}) che ci
- sono dati in ingresso. L'opzione utilizza per \param{optval} un intero che
- specifica il numero di byte, ma con Linux questo valore è sempre 1 e non può
- essere cambiato; \func{getsockopt} leggerà questo valore mentre
- \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}.
-
-\item[\constd{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
- numero minimo di byte che devono essere presenti nel buffer di trasmissione
- perché il kernel li invii al protocollo successivo, consentendo ad una
- \func{write} di ritornare o segnalando ad una \func{select} (vedi
- sez.~\ref{sec:TCP_sock_select}) che è possibile eseguire una scrittura.
- L'opzione utilizza per \param{optval} un intero che specifica il numero di
- byte, come per la precedente \const{SO\_RCVLOWAT} con Linux questo valore è
- sempre 1 e non può essere cambiato; \func{getsockopt} leggerà questo valore
- mentre \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}.
-
-\item[\constd{SO\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
- sulle operazioni di lettura da un socket, e prende per \param{optval} una
- struttura di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct})
- identica a quella usata con \func{select}. Con \func{getsockopt} si può
- leggere il valore attuale, mentre con \func{setsockopt} si imposta il tempo
- voluto, usando un valore nullo per \struct{timeval} il timeout viene
- rimosso.
-
- Se l'opzione viene attivata tutte le volte che una delle funzioni di lettura
- (\func{read}, \func{readv}, \func{recv}, \func{recvfrom} e \func{recvmsg})
- si blocca in attesa di dati per un tempo maggiore di quello impostato, essa
- ritornerà un valore -1 e la variabile \var{errno} sarà impostata con un
- errore di \errcode{EAGAIN} e \errcode{EWOULDBLOCK}, così come sarebbe
- avvenuto se si fosse aperto il socket in modalità non bloccante.\footnote{in
- teoria, se il numero di byte presenti nel buffer di ricezione fosse
- inferiore a quello specificato da \const{SO\_RCVLOWAT}, l'effetto potrebbe
- essere semplicemente quello di provocare l'uscita delle funzioni di
- lettura restituendo il numero di byte fino ad allora ricevuti; dato che
- con Linux questo valore è sempre 1 questo caso non esiste.}
-
- In genere questa opzione non è molto utilizzata se si ha a che fare con la
- lettura dei dati, in quanto è sempre possibile usare una \func{select} che
- consente di specificare un \textit{timeout}; l'uso di \func{select} non
- consente però di impostare il timeout per l'uso di \func{connect}, per avere
- il quale si può ricorrere a questa opzione.
-
-% TODO verificare il timeout con un programma di test
-
-\item[\constd{SO\_SNDTIMEO}] l'opzione permette di impostare un tempo massimo
- sulle operazioni di scrittura su un socket, ed usa gli stessi valori di
- \const{SO\_RCVTIMEO}. In questo caso però si avrà un errore di
- \errcode{EAGAIN} o \errcode{EWOULDBLOCK} per le funzioni di scrittura
- \func{write}, \func{writev}, \func{send}, \func{sendto} e \func{sendmsg}
- qualora queste restino bloccate per un tempo maggiore di quello specificato.
-
-\item[\constd{SO\_BSDCOMPAT}] questa opzione abilita la compatibilità con il
- comportamento di BSD (in particolare ne riproduce i bug). Attualmente è una
- opzione usata solo per il protocollo UDP e ne è prevista la rimozione in
- futuro. L'opzione utilizza per \param{optval} un intero usato come valore
- logico.
- Quando viene abilitata gli errori riportati da messaggi ICMP per un socket
- UDP non vengono passati al programma in user space. Con le versioni 2.0.x
- del kernel erano anche abilitate altre opzioni per i socket raw, che sono
- state rimosse con il passaggio al 2.2; è consigliato correggere i programmi
- piuttosto che usare questa funzione.
-
-\item[\constd{SO\_PASSCRED}] questa opzione abilita sui socket unix-domain
- (vedi sez.~\ref{sec:unix_socket}) la ricezione dei messaggi di controllo di
- tipo \const{SCM\_CREDENTIALS}. Prende come \param{optval} un intero usato
- come valore logico.
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{SO\_ACCEPTCONN}] questa opzione permette di rilevare se il socket
+ su cui opera è stato posto in modalità di ricezione di eventuali connessioni
+ con una chiamata a \func{listen}. L'opzione può essere usata soltanto con
+ \func{getsockopt} e utilizza per \param{optval} un intero in cui viene
+ restituito 1 se il socket è in ascolto e 0 altrimenti.
-\item[\constd{SO\_PEERCRED}] questa opzione restituisce le credenziali del
- processo remoto connesso al socket; l'opzione è disponibile solo per socket
- unix-domain e può essere usata solo con \func{getsockopt}. Utilizza per
- \param{optval} una apposita struttura \struct{ucred} (vedi
- sez.~\ref{sec:unix_socket}).
+\item[\constd{SO\_ATTACH\_FILTER}] questa opzione permette di agganciare ad un
+ socket un filtro di pacchetti che consente di selezionare quali pacchetti,
+ fra tutti quelli ricevuti, verranno letti. Viene usato principalmente con i
+ socket di tipo \const{PF\_PACKET} con la libreria \texttt{libpcap} per
+ implementare programmi di cattura dei pacchetti, torneremo su questo in
+ sez.~\ref{sec:packet_socket}.
\item[\constd{SO\_BINDTODEVICE}] questa opzione permette di \textsl{legare} il
socket ad una particolare interfaccia, in modo che esso possa ricevere ed
famiglia \const{AF\_INET}; non è invece supportata per i \textit{packet
socket} (vedi sez.~\ref{sec:socket_raw}).
+\item[\constd{SO\_BROADCAST}] questa opzione abilita il \textit{broadcast}:
+ quando abilitata i socket di tipo \const{SOCK\_DGRAM} riceveranno i
+ pacchetti inviati all'indirizzo di \textit{broadcast} e potranno scrivere
+ pacchetti su tale indirizzo. Prende per \param{optval} un intero usato come
+ valore logico. L'opzione non ha effetti su un socket di tipo
+ \const{SOCK\_STREAM}.
+
+\item[\constd{SO\_BSDCOMPAT}] questa opzione abilita la compatibilità con il
+ comportamento di BSD (in particolare ne riproduce alcuni bug). Attualmente è una
+ opzione usata solo per il protocollo UDP e ne è prevista la rimozione.
+ L'opzione utilizza per \param{optval} un intero usato come valore logico.
+
+ Quando viene abilitata gli errori riportati da messaggi ICMP per un socket
+ UDP non vengono passati al programma in user space. Con le versioni 2.0.x
+ del kernel erano anche abilitate altre opzioni di compatibilità per i socket
+ raw (modifiche casuali agli header, perdita del flag di \textit{broadcast})
+ che sono state rimosse con il passaggio al 2.2; è consigliato correggere i
+ programmi piuttosto che usare questa funzione. Dal kernel 2.4 viene
+ ignorata, e dal 2.6 genera un messaggio di log del kernel.
+
+\item[\constd{SO\_BUSY\_POLL}] questa opzione, presente dal kernel 3.11,
+ imposta un tempo approssimato in microsecondi, per cui in caso di ricezione
+ bloccante verrà eseguito un \itindex{busy~poll} ``\textit{busy
+ poll}'',\footnote{con \textit{busy poll} si fa riferimento al
+ \textit{polling} su una risorsa occupata; si continuerà cioè a tentare di
+ leggere anche quando non ci sono dati senza portare il processo stato di
+ \textit{sleep}, in alcuni casi, quando ci si aspetta che i dati arrivino a
+ breve, questa tecnica può dare un miglioramento delle prestazioni.} da
+ indicare in \param{optval} con un valore intero. Si tratta di una opzione
+ utilizzabile solo con socket che ricevono dati da un dispositivo di rete che
+ la supporti, e che consente di ridurre la latenza per alcune applicazioni,
+ ma che comporta un maggiore utilizzo della CPU (e quindi di energia); per
+ questo il valore può essere aumentato solo da processi con i privilegi di
+ amministratore (in particolare con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}). Il valore di default viene controllato dal file
+ \sysctlrelfile{net/core}{busy\_read} per le funzioni di lettura mentre il
+ file \sysctlrelfile{net/core}{busy\_poll} controlla il ``\textit{busy
+ poll}'' per \func{select} e \func{poll}.
+
\item[\constd{SO\_DEBUG}] questa opzione abilita il debugging delle operazioni
dei socket; l'opzione utilizza per \param{optval} un intero usato come
valore logico, e può essere utilizzata solo da un processo con i privilegi
sulla rete su un buffer circolare che viene letto da un apposito
programma, \cmd{trpt}.}
-\item[\const{SO\_REUSEADDR}] questa opzione permette di eseguire la funzione
- \func{bind} su indirizzi locali che siano già in uso da altri socket;
- l'opzione utilizza per \param{optval} un intero usato come valore logico.
- Questa opzione modifica il comportamento normale dell'interfaccia dei socket
- che fa fallire l'esecuzione della funzione \func{bind} con un errore di
- \errcode{EADDRINUSE} quando l'indirizzo locale\footnote{più propriamente il
- controllo viene eseguito sulla porta.} è già in uso da parte di un altro
- socket. Maggiori dettagli sul suo funzionamento sono forniti in
- sez.~\ref{sec:sock_options_main}.
+\item[\constd{SO\_DETACH\_FILTER}] consente di distaccare un filtro
+ precedentemente aggiunto ad un socket.
-\item[\constd{SO\_TYPE}] questa opzione permette di leggere il tipo di socket
- su cui si opera; funziona solo con \func{getsockopt}, ed utilizza per
- \param{optval} un intero in cui verrà restituito il valore numerico che lo
- identifica (ad esempio \const{SOCK\_STREAM}).
+% TODO documentare SO_ATTACH_FILTER e SO_DETACH_FILTER
+% riferimenti http://www.rcpt.to/lsfcc/lsf.html
+% Documentation/networking/filter.txt
-\item[\constd{SO\_ACCEPTCONN}] questa opzione permette di rilevare se il socket
- su cui opera è stato posto in modalità di ricezione di eventuali connessioni
- con una chiamata a \func{listen}. L'opzione può essere usata soltanto con
- \func{getsockopt} e utilizza per \param{optval} un intero in cui viene
- restituito 1 se il socket è in ascolto e 0 altrimenti.
+\item[\constd{SO\_DOMAIN}] questa opzione, presente dal kernel 2.6.32, legge
+ il ``\textsl{dominio}'' (la famiglia di indirizzi) del socket.
+. Funziona solo con \func{getsockopt}, ed
+ utilizza per \param{optval} un intero in cui verrà restituito il valore
+ numerico che lo identifica (ad esempio \texttt{AF\_INET}).
-\item[\constd{SO\_DONTROUTE}] questa opzione forza l'invio diretto dei
- pacchetti del socket, saltando ogni processo relativo all'uso della tabella
- di routing del kernel. Prende per \param{optval} un intero usato come valore
- logico.
+\item[\constd{SO\_DONTROUTE}] questa opzione richiede che l'invio dei
+ pacchetti del socket sia eseguito soltanto verso una destinazione
+ direttamente connessa, impedendo l'uso di un \textit{gateway} e saltando
+ ogni processo relativo all'uso della tabella di routing del kernel. Prende
+ per \param{optval} un intero usato come valore logico. È equivalente all'uso
+ del flag \const{MSG\_DONTROUTE} su una \func{send} (vedi
+ sez.~\ref{sec:net_send_recv}).
-\item[\constd{SO\_BROADCAST}] questa opzione abilita il \textit{broadcast};
- quanto abilitata i socket di tipo \const{SOCK\_DGRAM} riceveranno i
- pacchetti inviati all'indirizzo di \textit{broadcast}, e potranno scrivere
- pacchetti su tale indirizzo. Prende per \param{optval} un intero usato come
- valore logico. L'opzione non ha effetti su un socket di tipo
- \const{SOCK\_STREAM}.
+\item[\constd{SO\_ERROR}] questa opzione riceve un errore presente sul socket;
+ può essere utilizzata soltanto con \func{getsockopt} e prende per
+ \param{optval} un valore intero, nel quale viene restituito il codice di
+ errore, e la condizione di errore sul socket viene cancellata. Viene
+ usualmente utilizzata per ricevere il codice di errore, come accennato in
+ sez.~\ref{sec:TCP_sock_select}, quando si sta osservando il socket con una
+ \func{select} che ritorna a causa dello stesso.
-\item[\constd{SO\_SNDBUF}] questa opzione imposta la dimensione del buffer di
- trasmissione del socket. Prende per \param{optval} un intero indicante il
- numero di byte. Il valore di default ed il valore massimo che si possono
- specificare come argomento per questa opzione sono impostabili
- rispettivamente tramite gli opportuni valori di \func{sysctl} (vedi
- sez.~\ref{sec:sock_sysctl}).
+\item[\const{SO\_KEEPALIVE}] questa opzione abilita un meccanismo di verifica
+ della persistenza di una connessione associata al socket; è pertanto
+ effettiva solo sui socket che supportano le connessioni, ed è usata
+ principalmente con il TCP. L'opzione utilizza per \param{optval} un intero
+ usato come valore logico. Maggiori dettagli sul suo funzionamento sono
+ forniti in sez.~\ref{sec:sock_options_main}.
+
+\item[\const{SO\_LINGER}] questa opzione controlla le modalità con cui viene
+ chiuso un socket quando si utilizza un protocollo che supporta le
+ connessioni (è pertanto usata con i socket TCP ed ignorata per UDP) e
+ modifica il comportamento delle funzioni \func{close} e \func{shutdown}.
+ L'opzione richiede che l'argomento \param{optval} sia una struttura di tipo
+ \struct{linger}, definita in \headfile{sys/socket.h} ed illustrata in
+ fig.~\ref{fig:sock_linger_struct}. Maggiori dettagli sul suo funzionamento
+ sono forniti in sez.~\ref{sec:sock_options_main}.
+
+\item[\constd{SO\_MARK}] questa opzione, presente dal kernel 2.6.25, imposta
+ un valore di marcatura sui pacchetti del socket. Questa è una funzionalità
+ specifica di Linux, ottenibile anche con l'uso del target \texttt{MARK}
+ del comando \texttt{iptables} (l'argomento è trattato in sez.~3.3.5 di
+ \cite{SGL}). Il valore di marcatura viene mantenuto all'interno dello stack
+ di rete del kernel e può essere usato sia dal \itindex{netfilter}
+ \textit{netfilter}\footnote{il \textit{netfilter} è l'infrastruttura usata
+ per il filtraggio dei pacchetti del kernel, per maggiori dettagli si
+ consulti il cap.~2 di \cite{FwGL}.} di Linux che per impostare politiche
+ di routing avanzato. Il valore deve essere specificato in \param{optval}
+ come un intero. L'opzione richiede i privilegi di amministratore con la
+ \textit{capability} \const{CAP\_NET\_ADMIN}.
+
+\item[\constd{SO\_OOBINLINE}] se questa opzione viene abilitata i dati
+ \textit{out-of-band} vengono inviati direttamente nel flusso di dati del
+ socket (e sono quindi letti con una normale \func{read}) invece che restare
+ disponibili solo per l'accesso con l'uso del flag \const{MSG\_OOB} di
+ \func{recvmsg}. L'argomento è trattato in dettaglio in
+ sez.~\ref{sec:TCP_urgent_data}. L'opzione funziona soltanto con socket che
+ supportino i dati \textit{out-of-band} (non ha senso per socket UDP ad
+ esempio), ed utilizza per \param{optval} un intero usato come valore logico.
+
+\item[\constd{SO\_PASSCRED}] questa opzione abilita sui socket unix-domain
+ (vedi sez.~\ref{sec:unix_socket}) la ricezione dei messaggi di controllo di
+ tipo \const{SCM\_CREDENTIALS}. Prende come \param{optval} un intero usato
+ come valore logico.
+
+\item[\constd{SO\_PEEK\_OFF}] questa opzione, disponibile a partire dal kernel
+ 3.4, imposta un ``\textit{peek offset}'' sul socket (attualmente disponibile
+ solo per i socket unix-domain (vedi sez.~\ref{sec:unix_socket}). La funzione
+ serve come ausilio per l'uso del flag \const{MSG\_PEEK} di \func{recv} che
+ consente di ``\textsl{sbirciare}'' nei dati di un socket, cioè di leggerli
+ senza rimuoverli dalla coda in cui sono mantenuti, così che vengano
+ restituiti anche da una successiva lettura ordinaria.
+
+ Un valore negativo (il default è $-1$) riporta alla situazione ordinaria in
+ cui si ``\textsl{sbircia}'' a partire dalla testa della coda, un valore
+ positivo consente di leggere a partire dalla posizione indicata nella coda e
+ tutte le volte che si sbirciano dei dati il valore dell'offset viene
+ automaticamente aumentato della quantità di dati sbirciati, in modo che si
+ possa proseguire da dove si era arrivati. Il valore deve essere specificato
+ in \param{optval} come intero.
+
+\item[\constd{SO\_PEERCRED}] questa opzione restituisce le credenziali del
+ processo remoto connesso al socket; l'opzione è disponibile solo per socket
+ unix-domain di tipo \textit{stream} e anche per quelli di tipo
+ \textit{datagram} quando se ne crea una coppia con \func{socketpair}, e può
+ essere usata solo con \func{getsockopt}. Utilizza per
+ \param{optval} una apposita struttura \struct{ucred} (vedi
+ sez.~\ref{sec:unix_socket}).
+
+\item[\constd{SO\_PRIORITY}] questa opzione permette di impostare le priorità
+ per tutti i pacchetti che sono inviati sul socket, prende per \param{optval}
+ un valore intero. Con questa opzione il kernel usa il valore per ordinare le
+ priorità sulle code di rete,\footnote{questo richiede che sia abilitato il
+ sistema di \textit{Quality of Service} disponibile con le opzioni di
+ routing avanzato.} i pacchetti con priorità più alta vengono processati
+ per primi, in modalità che dipendono dalla disciplina di gestione della
+ coda. Nel caso di protocollo IP questa opzione permette anche di impostare i
+ valori del campo \textit{type of service} (noto come TOS, vedi
+ sez.~\ref{sec:IP_header}) per i pacchetti uscenti. Per impostare una
+ priorità al di fuori dell'intervallo di valori fra 0 e 6 sono richiesti i
+ privilegi di amministratore con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}.
+
+\item[\constd{SO\_PROTOCOL}] questa opzione, presente dal kernel 2.6.32, legge
+ il protocollo usato dal socket. Funziona solo con \func{getsockopt}, ed
+ utilizza per \param{optval} un intero in cui verrà restituito il valore
+ numerico che lo identifica (ad esempio \texttt{IPPROTO\_TCP}).
\item[\constd{SO\_RCVBUF}] questa opzione imposta la dimensione del buffer di
ricezione del socket. Prende per \param{optval} un intero indicante il
essere effettive, devono essere impostate prima della chiamata alle funzioni
\func{listen} o \func{connect}.
-\item[\const{SO\_LINGER}] questa opzione controlla le modalità con cui viene
- chiuso un socket quando si utilizza un protocollo che supporta le
- connessioni (è pertanto usata con i socket TCP ed ignorata per UDP) e
- modifica il comportamento delle funzioni \func{close} e \func{shutdown}.
- L'opzione richiede che l'argomento \param{optval} sia una struttura di tipo
- \struct{linger}, definita in \headfile{sys/socket.h} ed illustrata in
- fig.~\ref{fig:sock_linger_struct}. Maggiori dettagli sul suo funzionamento
- sono forniti in sez.~\ref{sec:sock_options_main}.
+\item[\constd{SO\_RCVBUFFORCE}] questa opzione, presente dal kernel 2.6.14, è
+ identica a \const{SO\_RCVBUF} ma consente ad un processo con i privilegi di
+ amministratore (con la \textit{capability} \const{CAP\_NET\_ADMIN}) di
+ impostare in valore maggiore del limite di
+ \sysctlrelfile{net/core}{rmem\_max}.
-\item[\constd{SO\_PRIORITY}] questa opzione permette di impostare le priorità
- per tutti i pacchetti che sono inviati sul socket, prende per \param{optval}
- un valore intero. Con questa opzione il kernel usa il valore per ordinare le
- priorità sulle code di rete,\footnote{questo richiede che sia abilitato il
- sistema di \textit{Quality of Service} disponibile con le opzioni di
- routing avanzato.} i pacchetti con priorità più alta vengono processati
- per primi, in modalità che dipendono dalla disciplina di gestione della
- coda. Nel caso di protocollo IP questa opzione permette anche di impostare i
- valori del campo \textit{type of service} (noto come TOS, vedi
- sez.~\ref{sec:IP_header}) per i pacchetti uscenti. Per impostare una
- priorità al di fuori dell'intervallo di valori fra 0 e 6 sono richiesti i
- privilegi di amministratore con la capability \const{CAP\_NET\_ADMIN}.
+\item[\constd{SO\_RCVLOWAT}] questa opzione imposta il valore che indica il
+ numero minimo di byte che devono essere presenti nel buffer di ricezione
+ perché il kernel passi i dati all'utente, restituendoli ad una \func{read} o
+ segnalando ad una \func{select} (vedi sez.~\ref{sec:TCP_sock_select}) che ci
+ sono dati in ingresso. L'opzione utilizza per \param{optval} un intero che
+ specifica il numero di byte; con Linux questo valore è sempre 1 e può essere
+ cambiato solo con i kernel a partire dal 2.4. Si tenga presente però che
+ \func{poll} e \func{select} non supportano ancora questa funzionalità e
+ ritornano comunque, indicando il socket come leggibile, non appena almeno un
+ byte è presente mentre in una successiva lettura \func{read} si bloccherà
+ fintanto che non siano disponibili la quantità di byte indicati. Con
+ \func{getsockopt} si può leggere questo valore mentre \func{setsockopt} darà
+ un errore di \errcode{ENOPROTOOPT} quando il cambiamento non è supportato.
-\item[\constd{SO\_ERROR}] questa opzione riceve un errore presente sul socket;
- può essere utilizzata soltanto con \func{getsockopt} e prende per
- \param{optval} un valore intero, nel quale viene restituito il codice di
- errore, e la condizione di errore sul socket viene cancellata. Viene
- usualmente utilizzata per ricevere il codice di errore, come accennato in
- sez.~\ref{sec:TCP_sock_select}, quando si sta osservando il socket con una
- \func{select} che ritorna a causa dello stesso.
+\item[\constd{SO\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
+ sulle operazioni di lettura da un socket, e prende per \param{optval} una
+ struttura di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct})
+ identica a quella usata con \func{select}. Con \func{getsockopt} si può
+ leggere il valore attuale, mentre con \func{setsockopt} si imposta il tempo
+ voluto, usando un valore nullo per \struct{timeval} il timeout viene
+ rimosso.
-\item[\constd{SO\_ATTACH\_FILTER}] questa opzione permette di agganciare ad un
- socket un filtro di pacchetti che consente di selezionare quali pacchetti,
- fra tutti quelli ricevuti, verranno letti. Viene usato principalmente con i
- socket di tipo \const{PF\_PACKET} con la libreria \texttt{libpcap} per
- implementare programmi di cattura dei pacchetti, torneremo su questo in
- sez.~\ref{sec:packet_socket}.
+ Se l'opzione viene attivata tutte le volte che una delle funzioni di lettura
+ (\func{read}, \func{readv}, \func{recv}, \func{recvfrom} e \func{recvmsg})
+ si blocca in attesa di dati per un tempo maggiore di quello impostato, essa
+ ritornerà un valore -1 e la variabile \var{errno} sarà impostata con un
+ errore di \errcode{EAGAIN} e \errcode{EWOULDBLOCK}, così come sarebbe
+ avvenuto se si fosse aperto il socket in modalità non bloccante.\footnote{in
+ teoria, se il numero di byte presenti nel buffer di ricezione fosse
+ inferiore a quello specificato da \const{SO\_RCVLOWAT}, l'effetto potrebbe
+ essere semplicemente quello di provocare l'uscita delle funzioni di
+ lettura restituendo il numero di byte fino ad allora ricevuti.}
+
+ In genere questa opzione non è molto utilizzata se si ha a che fare con la
+ lettura dei dati, in quanto è sempre possibile usare una \func{select} che
+ consente di specificare un \textit{timeout}; l'uso di \func{select} non
+ consente però di impostare il timeout per l'uso di \func{connect}, per avere
+ il quale si può ricorrere a questa opzione (nel qual caso il raggiungimento
+ del \textit{timeout} restituisce l'errore \errcode{EINPROGRESS}).
+
+\item[\const{SO\_REUSEADDR}] questa opzione permette di eseguire la funzione
+ \func{bind} su indirizzi locali che siano già in uso da altri socket;
+ l'opzione utilizza per \param{optval} un intero usato come valore logico.
+ Questa opzione modifica il comportamento normale dell'interfaccia dei socket
+ che fa fallire l'esecuzione della funzione \func{bind} con un errore di
+ \errcode{EADDRINUSE} quando l'indirizzo locale (più propriamente il
+ controllo viene eseguito sulla porta) è già in uso da parte di un altro
+ socket. Maggiori dettagli sul suo funzionamento sono forniti in
+ sez.~\ref{sec:sock_options_main}.
+
+
+\item[\const{SO\_REUSEPORT}] questa opzione, presente a partire dal kernel
+ 3.9, permette di far usare a più socket di tipo \const{AF\_INET} o
+ \const{AF\_INET6} lo stesso indirizzo locale. 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 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?
+
+
+\item[\constd{SO\_RXQ\_OVFL}] questa opzione, presente dal kernel 2.6.33,
+ permette di abilitare o disabilitare sul socket la ricezione di un messaggio
+ ancillare (tratteremo l'argomento in sez.~\ref{sec:net_ancillary_data})
+ contenente un intero senza segno a 32 bit che indica il numero di pacchetti
+ scartati sul socket fra l'ultimo pacchetto ricevuto e questo. L'opzione
+ utilizza per \param{optval} un intero usato come valore logico.
+
+% TODO documentare SO_RXQ_OVFL, vedi https://lwn.net/Articles/626150/ capire
+% che significa 'questo'
+
+\item[\constd{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
+ numero minimo di byte che devono essere presenti nel buffer di trasmissione
+ perché il kernel li invii al protocollo successivo, consentendo ad una
+ \func{write} di ritornare o segnalando ad una \func{select} (vedi
+ sez.~\ref{sec:TCP_sock_select}) che è possibile eseguire una scrittura.
+ L'opzione utilizza per \param{optval} un intero che specifica il numero di
+ byte; con Linux questo valore è sempre 1 e non può essere cambiato;
+ \func{getsockopt} leggerà questo valore mentre \func{setsockopt} darà un
+ errore di \errcode{ENOPROTOOPT}.
+
+\item[\constd{SO\_SNDBUF}] questa opzione imposta la dimensione del buffer di
+ trasmissione del socket. Prende per \param{optval} un intero indicante il
+ numero di byte. Il valore di default ed il valore massimo che si possono
+ specificare come argomento per questa opzione sono impostabili
+ rispettivamente tramite gli opportuni valori di \func{sysctl} (vedi
+ sez.~\ref{sec:sock_sysctl}).
+
+\item[\constd{SO\_SNDBUFFORCE}] questa opzione, presente dal kernel 2.6.14, è
+ identica a \const{SO\_SNDBUF} ma consente ad un processo con i privilegi di
+ amministratore (con la \textit{capability} \const{CAP\_NET\_ADMIN}) di
+ impostare in valore maggiore del limite di
+ \sysctlrelfile{net/core}{wmem\_max}.
+
+% TODO verificare il timeout con un programma di test
+
+\item[\constd{SO\_SNDTIMEO}] l'opzione permette di impostare un tempo massimo
+ sulle operazioni di scrittura su un socket, ed usa gli stessi valori di
+ \const{SO\_RCVTIMEO}. In questo caso però si avrà un errore di
+ \errcode{EAGAIN} o \errcode{EWOULDBLOCK} per le funzioni di scrittura
+ \func{write}, \func{writev}, \func{send}, \func{sendto} e \func{sendmsg}
+ qualora queste restino bloccate per un tempo maggiore di quello specificato.
+
+\item[\constd{SO\_TIMESTAMP}] questa opzione, presente dal kernel 2.6.30,
+ permette di abilitare o disabilitare sul socket la ricezione di un messaggio
+ ancillare di tipo \const{SO\_TIMESTAMP}. Il messaggio viene inviato con
+ livello \const{SOL\_SOCKET} ed nel campo \var{cmsg\_data} (per i dettagli si
+ veda sez.~\ref{sec:net_ancillary_data}) viene impostata una struttura
+ \struct{timeval} che indica il tempo di ricezione dell'ultimo pacchetto
+ passato all'utente. L'opzione utilizza per \param{optval} un intero usato
+ come valore logico.
+
+% TODO capire meglio la tempistica di questi messaggi ancillari
+% TODO documentare SO_TIMESTAMP e le altre opzioni di timestamping dei
+% pacchetti, introdotte nel 2.6.30, vedi nei sorgenti del kernel:
+% Documentation/networking/timestamping.txt
+
+\item[\constd{SO\_TYPE}] questa opzione permette di leggere il tipo di socket
+ su cui si opera; funziona solo con \func{getsockopt}, ed utilizza per
+ \param{optval} un intero in cui verrà restituito il valore numerico che lo
+ identifica (ad esempio \const{SOCK\_STREAM}).
\item[\constd{SO\_DETACH\_FILTER}] consente di distaccare un filtro
precedentemente aggiunto ad un socket.
% TOFO documentare SO_REUSEPORT introdotta con il kernel 3.9, vedi
% http://git.kernel.org/linus/c617f398edd4db2b8567a28e899a88f8f574798d
+% TODO documentare SO_PEERGROUPS introdotta con il kernel 4.13, citata
+% in https://lwn.net/Articles/727385/
+
+
\end{basedescript}
principalmente ai socket TCP.
Con le impostazioni di default (che sono riprese da BSD) Linux emette un
-messaggio di \textit{keep-alive}\footnote{in sostanza un segmento ACK vuoto,
- cui sarà risposto con un altro segmento ACK vuoto.} verso l'altro capo della
-connessione se questa è rimasta senza traffico per più di due ore. Se è tutto
-a posto il messaggio viene ricevuto e verrà emesso un segmento ACK di
-risposta, alla cui ricezione ripartirà un altro ciclo di attesa per altre due
-ore di inattività; il tutto avviene all'interno del kernel e le applicazioni
-non riceveranno nessun dato.
+messaggio di \textit{keep-alive} (in sostanza un segmento ACK vuoto, cui sarà
+risposto con un altro segmento ACK vuoto) verso l'altro capo della connessione
+se questa è rimasta senza traffico per più di due ore. Se è tutto a posto il
+messaggio viene ricevuto e verrà emesso un segmento ACK di risposta, alla cui
+ricezione ripartirà un altro ciclo di attesa per altre due ore di inattività;
+il tutto avviene all'interno del kernel e le applicazioni non riceveranno
+nessun dato.
Qualora ci siano dei problemi di rete si possono invece verificare i due casi
di terminazione precoce del server già illustrati in
Abilitandola dopo un certo tempo le connessioni effettivamente terminate
verranno comunque chiuse per cui, utilizzando ad esempio una \func{select}, se
-be potrà rilevare la conclusione e ricevere il relativo errore. Si tenga
+ne potrà rilevare la conclusione e ricevere il relativo errore. Si tenga
presente però che non può avere la certezza assoluta che un errore di
\errcode{ETIMEDOUT} ottenuto dopo aver abilitato questa opzione corrisponda
necessariamente ad una reale conclusione della connessione, il problema
cui è prevista la possibilità di un utilizzo di questa opzione, il che la
rende una delle più difficili da capire.
-Il primo caso, che è anche il più comune, in cui si fa ricorso a
-\const{SO\_REUSEADDR} è quello in cui un server è terminato ma esistono ancora
-dei processi figli che mantengono attiva almeno una connessione remota che
-utilizza l'indirizzo locale, mantenendo occupata la porta. Quando si riesegue
-il server allora questo riceve un errore sulla chiamata a \func{bind} dato che
-la porta è ancora utilizzata in una connessione esistente.\footnote{questa è
- una delle domande più frequenti sui newsgroup dedicati allo sviluppo, in
- quanto è piuttosto comune trovarsi in questa situazione quando si sta
- sviluppando un server che si ferma e si riavvia in continuazione dopo aver
- fatto modifiche.} Inoltre se si usa il protocollo TCP questo può avvenire
-anche dopo tutti i processi figli sono terminati, dato che una connessione può
+Il primo caso in cui si fa ricorso a \const{SO\_REUSEADDR}, che è anche il più
+comune, è quello in cui un server è terminato ma esistono ancora dei processi
+figli che mantengono attiva almeno una connessione remota che utilizza
+l'indirizzo locale, mantenendo occupata la porta. Quando si riesegue il server
+allora questo riceve un errore sulla chiamata a \func{bind} dato che la porta
+è ancora utilizzata in una connessione esistente.\footnote{questa è una delle
+ domande più frequenti sui newsgroup dedicati allo sviluppo, in quanto è
+ piuttosto comune trovarsi in questa situazione quando si sta sviluppando un
+ server che si ferma e si riavvia in continuazione dopo aver fatto
+ modifiche.} Inoltre se si usa il protocollo TCP questo può avvenire anche
+dopo tutti i processi figli 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}).
eventuali pacchetti rimasti intrappolati in una precedente connessione possano
finire fra quelli di una nuova.
-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 è
-\texttt{sockbindopt}, e le principali differenze rispetto alla precedente sono
-illustrate in fig.~\ref{fig:sockbindopt_code}, dove si sono riportate le
-sezioni di codice modificate rispetto alla versione precedente. Il codice
-completo della funzione si trova, insieme alle altre funzioni di servizio dei
-socket, all'interno del file \texttt{SockUtils.c} dei sorgenti allegati alla
-guida.
-
\begin{figure}[!htbp]
\footnotesize \centering
\begin{minipage}[c]{\codesamplewidth}
\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 è
+\texttt{sockbindopt}, e le principali differenze rispetto alla precedente sono
+illustrate in fig.~\ref{fig:sockbindopt_code}, dove si sono riportate le
+sezioni di codice modificate rispetto alla versione precedente. Il codice
+completo della funzione si trova, insieme alle altre funzioni di servizio dei
+socket, all'interno del file \texttt{SockUtils.c} dei sorgenti allegati alla
+guida.
+
In realtà tutto quello che si è fatto è stato introdurre nella nuova funzione
(\texttt{\small 1}) un nuovo argomento intero, \param{reuse}, che conterrà il
valore logico da usare nella successiva chiamata (\texttt{\small 14}) a
esegue l'impostazione dell'opzione fra la chiamata a \func{socket} e quella a
\func{bind}.
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/TCP_echod_fifth.c}
+ \end{minipage}
+ \normalsize
+ \caption{Il nuovo codice per l'apertura passiva del server \textit{echo} che
+ usa la nuova funzione \texttt{sockbindopt}.}
+ \label{fig:TCP_echod_fifth}
+\end{figure}
A questo punto basterà modificare il server per utilizzare la nuova
funzione; in fig.~\ref{fig:TCP_echod_fifth} abbiamo riportato le sezioni
valore, per cui in tal caso la successiva chiamata (\texttt{\small 13--17}) a
\func{setsockopt} attiverà l'opzione \const{SO\_REUSEADDR}.
-\begin{figure}[!htbp]
- \footnotesize \centering
- \begin{minipage}[c]{\codesamplewidth}
- \includecodesample{listati/TCP_echod_fifth.c}
- \end{minipage}
- \normalsize
- \caption{Il nuovo codice per l'apertura passiva del server \textit{echo} che
- usa la nuova funzione \texttt{sockbindopt}.}
- \label{fig:TCP_echod_fifth}
-\end{figure}
-
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
\textit{multi-homed}) e si vuole porre in ascolto sulla stessa porta un
sull'indirizzo generico, e questo permetterà il collegamento per tutti gli
indirizzi (di quelli presenti) per i quali la porta non risulti occupata da
una precedente chiamata più specifica. Infine si tenga presente che con il
-protocollo TCP non è mai possibile far partire server che eseguano \func{bind}
-sullo stesso indirizzo e la stessa porta, cioè ottenere quello che viene
-chiamato un \textit{completely duplicate binding}.
+protocollo TCP non è in genere possibile far partire server che eseguano
+\func{bind} sullo stesso indirizzo e la stessa porta, cioè ottenere quello che
+viene chiamato un \textit{completely duplicate binding}.
Il terzo impiego è simile al precedente e prevede l'uso di \func{bind}
all'interno dello stesso programma per associare indirizzi locali diversi a
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\footnote{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.} o da diverse istanze della stessa applicazione.
+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
applicazione eseguire \func{bind} sulla stessa porta ed indirizzo usata da
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 (unicast).
+normale (\textit{unicast}).
+
+% TODO documentare SO_REUSEPORT, vedi https://lwn.net/Articles/542260/
Essendo questo un caso particolare in alcuni sistemi (come BSD) è stata
introdotta una opzione ulteriore, \const{SO\_REUSEPORT} che richiede che detta
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.\footnote{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}.}
+\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.
\constend{SO\_REUSEADDR}
-% TODO documentare SO_REUSEPORT, vedi https://lwn.net/Articles/542260/
\constbeg{SO\_LINGER}
\subsubsection{L'opzione \const{SO\_LINGER}}
\label{sec:sock_ipv4_options}
Il secondo insieme di opzioni dei socket che tratteremo è quello relativo ai
-socket che usano il protocollo IPv4.\footnote{come per le precedenti opzioni
- generiche una descrizione di esse è disponibile nella settima sezione delle
- pagine di manuale, nel caso specifico la documentazione si può consultare
- con \texttt{man 7 ip}.} 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.
+socket che usano il protocollo IPv4; come per le precedenti opzioni generiche
+una descrizione di esse è disponibile nella settima sezione delle pagine di
+manuale, nel caso specifico la documentazione si può consultare con
+\texttt{man 7 ip}.
\begin{table}[!htb]
\centering
\footnotesize
- \begin{tabular}[c]{|l|c|c|c|l|p{6cm}|}
+ \begin{tabular}[c]{|l|c|c|c|l|p{5.cm}|}
\hline
\textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
\textbf{Descrizione}\\
\hline
\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}&
+ Si unisce a un gruppo di \textit{multicast} per una sorgente.\\
+ \const{IP\_DROP\_MEMBERSHIP}& &$\bullet$& &\struct{ip\_mreqn}&
+ Si sgancia da un gruppo di \textit{multicast}.\\
+ \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\_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\_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\_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.\\
+ \const{IP\_RECVERR} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Abilita la gestione degli errori.\\
+ \const{IP\_RECVOPTS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
+ Passa un messaggio con le opzioni IP.\\
\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.\\
- \const{IP\_RECVOPTS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Passa un messaggio con le opzioni IP.\\
\const{IP\_RETOPTS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Passa un messaggio 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\_TTL} &$\bullet$&$\bullet$& &\texttt{int}&
Imposta il valore del campo TTL.\\
- \const{IP\_MINTTL} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta il valore minimo del TTL per i pacchetti accettati.\\
- \const{IP\_HDRINCL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Passa l'intestazione di IP nei dati.\\
- \const{IP\_RECVERR} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Abilita la gestione degli errori.\\
- \const{IP\_MTU\_DISCOVER} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta il \textit{Path MTU Discovery}.\\
- \const{IP\_MTU} &$\bullet$& & &\texttt{int}&
- Legge il valore attuale della MTU.\\
- \const{IP\_ROUTER\_ALERT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Imposta l'opzione \textit{IP router alert} sui pacchetti.\\
- \const{IP\_MULTICAST\_TTL} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta il TTL per i pacchetti \textit{multicast}.\\
- \const{IP\_MULTICAST\_LOOP} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
- Controlla il reinvio a se stessi dei dati di \textit{multicast}.\\
- \const{IP\_ADD\_MEMBERSHIP} & &$\bullet$& &\struct{ip\_mreqn}&
- Si unisce a un gruppo di \textit{multicast}.\\
- \const{IP\_DROP\_MEMBERSHIP}& &$\bullet$& &\struct{ip\_mreqn}&
- Si sgancia da un gruppo di \textit{multicast}.\\
- \const{IP\_MULTICAST\_IF} & &$\bullet$& &\struct{ip\_mreqn}&
- Imposta l'interfaccia locale di un socket \textit{multicast}.\\
\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.
+
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{1.5cm}\desclabelstyle{\nextlinelabel}}
+\begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}}
\item[\constd{IP\_OPTIONS}] l'opzione permette di impostare o leggere le
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 capability
+ 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
Trip Time} cui abbiamo già accennato in sez.~\ref{sec:net_tcp}.} dei
pacchetti sulla rete.
-\item[\constd{SIOCSPGRP}] imposta il processo o il \textit{process group} a cui
- inviare i segnali \signal{SIGIO} e \signal{SIGURG} quando viene completata
- una operazione di I/O asincrono o arrivano dei dati urgenti
+\item[\constd{SIOCSPGRP}] imposta il processo o il \textit{process group} a
+ cui inviare i segnali \signal{SIGIO} e \signal{SIGURG} quando viene
+ completata una operazione di I/O asincrono o arrivano dei dati urgenti
(\texttt{out-of-band}). Il terzo argomento deve essere un puntatore ad una
variabile di tipo \type{pid\_t}; un valore positivo indica direttamente il
\ids{PID} del processo, mentre un valore negativo indica (col valore
assoluto) il \textit{process group}. Senza privilegi di amministratore o la
- capability \const{CAP\_KILL} si può impostare solo se stessi o il proprio
- \textit{process group}.
+ \textit{capability} \const{CAP\_KILL} si può impostare solo se stessi o il
+ proprio \textit{process group}.
\item[\constd{SIOCGPGRP}] legge le impostazioni presenti sul socket
relativamente all'eventuale processo o \textit{process group} cui devono
Il \textit{bucket filter} è un algoritmo generico che permette di impostare
dei limiti di flusso su una quantità\footnote{uno analogo viene usato per
- imporre dei limiti sul flusso dei pacchetti nel \itindex{netfilter}
- \textit{netfilter} di Linux (il \textit{netfilter} è l'infrastruttura
- usata per il filtraggio dei pacchetti del kernel, per maggiori dettagli si
- consulti il cap.~2 di \cite{FwGL}).} senza dovere eseguire medie
- temporali, che verrebbero a dipendere in misura non controllabile dalla
- dimensione dell'intervallo su cui si media e dalla distribuzione degli
- eventi;\footnote{in caso di un picco di flusso (il cosiddetto
- \textit{burst}) il flusso medio verrebbe a dipendere in maniera esclusiva
- dalla dimensione dell'intervallo di tempo su cui calcola la media.} in
- questo caso si definisce la dimensione di un ``\textsl{bidone}'' (il
- \textit{bucket}) e del flusso che da esso può uscire, la presenza di una
- dimensione iniziale consente di assorbire eventuali picchi di emissione,
- l'aver fissato un flusso di uscita garantisce che a regime questo sarà il
- valore medio del flusso ottenibile dal \textit{bucket}.
+ imporre dei limiti sul flusso dei pacchetti nel \textit{netfilter} di
+ Linux.} senza dovere eseguire medie temporali, che verrebbero a dipendere
+ in misura non controllabile dalla dimensione dell'intervallo su cui si media
+ e dalla distribuzione degli eventi;\footnote{in caso di un picco di flusso
+ (il cosiddetto \textit{burst}) il flusso medio verrebbe a dipendere in
+ maniera esclusiva dalla dimensione dell'intervallo di tempo su cui calcola
+ la media.} in questo caso si definisce la dimensione di un
+ ``\textsl{bidone}'' (il \textit{bucket}) e del flusso che da esso può
+ uscire, la presenza di una dimensione iniziale consente di assorbire
+ eventuali picchi di emissione, l'aver fissato un flusso di uscita garantisce
+ che a regime questo sarà il valore medio del flusso ottenibile dal
+ \textit{bucket}.
\itindend{bucket~filter}