\hline
\const{SO\_ACCEPTCONN}&$\bullet$& & &\texttt{int}&
Indica se il socket è in ascolto.\\
+ \const{SO\_ATTACH\_FILTER}& &$\bullet$& &\texttt{sock\_fprog}&
+ Aggancia un filtro BPF al socket.\\
\const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$& &\texttt{char *}&
Lega il socket ad un dispositivo.\\
\const{SO\_BROADCAST}&$\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\_DETACH\_FILTER}& &$\bullet$&$\bullet$&\texttt{int}&
+ Rimuove il filtro BPF agganciato al socket.\\
\const{SO\_DOMAIN} &$\bullet$& & &\texttt{int}&
Legge il tipo di socket.\\
\const{SO\_DONTROUTE}&$\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\_LOCK\_FILTER}& &$\bullet$&$\bullet$&\texttt{int}&
+ Blocca il filtro BPF agganciato al socket.\\
\const{SO\_MARK} &$\bullet$&$\bullet$& &\texttt{int}&
Imposta un ``\textit{firewall mark}'' sul socket.\\
\const{SO\_OOBINLINE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
% 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,
-
+% TODO documentare SO_PEERGROUPS introdotta con il kernel 4.13, citata
+% in https://lwn.net/Articles/727385/
+% TODO documentare SO_ZEROCOPY, vedi https://lwn.net/Articles/726917/ (e il
+% resto pure) introdotta con il kernel 4.14
La tabella elenca le costanti che identificano le singole opzioni da usare
come valore per \param{optname}; le due colonne seguenti indicano per quali
\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.
+ \func{getsockopt} ed utilizza per \param{optval} un intero in cui viene
+ restituito 1 se il socket è in ascolto e 0 altrimenti.
\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}.
+ socket un filtro di selezione dei pacchetti con la stessa sintassi del BPF
+ (\textit{Berkley Packet Filter}) di BSD, che consente di selezionare, fra
+ tutti quelli ricevuti, verranno letti. Può essere usata solo con
+ \func{setsockopt} ed utilizza per \param{optval} un puntatore ad una
+ struttura \struct{sock\_fprog} (definita in
+ \headfile{linux/filter.h}). Questa opzione viene usata principalmente con i
+ socket di tipo \const{PF\_PACKET} (torneremo su questo in
+ sez.~\ref{sec:packet_socket}) dalla libreria \texttt{libpcap} per
+ implementare programmi di cattura dei pacchetti, e per questo tipo di
+ applicazione è opportuno usare sempre quest'ultima.\footnote{la trattazione
+ del BPF va al di là dell'argomento di questa sezione per la documentazione
+ si consulti il file \texttt{networking/filter.txt} nella documentazione
+ del kernel.}
\item[\constd{SO\_BINDTODEVICE}] questa opzione permette di \textsl{legare} il
socket ad una particolare interfaccia, in modo che esso possa ricevere ed
programma, \cmd{trpt}.}
\item[\constd{SO\_DETACH\_FILTER}] consente di distaccare un filtro
- precedentemente aggiunto ad un socket.
-
-% TODO documentare SO_ATTACH_FILTER e SO_DETACH_FILTER
-% riferimenti http://www.rcpt.to/lsfcc/lsf.html
-% Documentation/networking/filter.txt
+ precedentemente aggiunto ad un socket con l'opzione
+ \const{SO\_ATTACH\_FILTER}, in genere non viene usata direttamente in quanto
+ i filtri BPF vengono automaticamente rimossi alla chiusura del socket, il
+ suo utilizzo è pertanto limitato ai rari casi in cui si vuole rimuovere un
+ precedente filtro per inserirne uno diverso. Come \const{SO\_ATTACH\_FILTER}
+ può essere usato solo \func{setsockopt} e prende per \param{optval} un
+ intero usato come valore logico.
\item[\constd{SO\_DOMAIN}] questa opzione, presente dal kernel 2.6.32, legge
il ``\textsl{dominio}'' (la famiglia di indirizzi) del socket.
fig.~\ref{fig:sock_linger_struct}. Maggiori dettagli sul suo funzionamento
sono forniti in sez.~\ref{sec:sock_options_main}.
+\item[\constd{SO\_LOCK\_FILTER}] consente di bloccare un filtro
+ precedentemente aggiunto ad un socket con l'opzione
+ \const{SO\_ATTACH\_FILTER}, in modo che non possa essere né rimosso né
+ modificato, questo consente di impostare un filtro su un socket, bloccarlo e
+ poi cedere i privilegi con la sicurezza che il filtro permarrà fino alla
+ chiusura del socket. Come \const{SO\_ATTACH\_FILTER} può essere usato solo
+ \func{setsockopt} e prende per \param{optval} un intero usato come valore
+ logico.
+
\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}
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?
-
+ \const{AF\_INET6} lo stesso indirizzo locale, e costituisce una estensione
+ della precedente \const{SO\_REUSEADDR}. Maggiori dettagli sul suo
+ funzionamento sono forniti in sez.~\ref{sec:sock_options_main}.
\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
\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.
-
-% TODO documentare SO_ATTACH_FILTER e SO_DETACH_FILTER
-% riferimenti http://www.rcpt.to/lsfcc/lsf.html
-% Documentation/networking/filter.txt
-
-% TODO documentare SO_MARK, introdotta nel 2.6.25, richiede CAP_NET_ADMIN
-%A userspace program may wish to set the mark for each packets its send
-%without using the netfilter MARK target. Changing the mark can be used
-%for mark based routing without netfilter or for packet filtering.
-
-
-% 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
-
-
-% 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}
\constbeg{SO\_REUSEADDR}
-\subsubsection{L'opzione \const{SO\_REUSEADDR}}
+\subsubsection{Le opzioni \const{SO\_REUSEADDR} e \const{SO\_REUSEADDR}}
-La seconda opzione da approfondire è \const{SO\_REUSEADDR}, che consente di
+La seconda opzione da approfondire è \constd{SO\_REUSEADDR}, che consente di
eseguire \func{bind} su un socket anche quando la porta specificata è già in
uso da parte di un altro socket. Si ricordi infatti che, come accennato in
sez.~\ref{sec:TCP_func_bind}, normalmente la funzione \func{bind} fallisce con
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}).
+ domande più frequenti relative 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}).
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
\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 è
Usando questa opzione diventa anche possibile eseguire \func{bind}
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 è 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}.
+una precedente chiamata più specifica. Si tenga presente infatti che con il
+protocollo TCP non è in genere possibile far partire più server che eseguano
+\func{bind} sullo stesso indirizzo e la stessa porta se su di esso c'è già un
+socket in ascolto, cioè ottenere quello che viene chiamato un
+\itindex{completely~duplicate~binding} \textit{completely duplicate binding}
+(per questo è stata introdotta \const{SO\_REUSEPORT}).
Il terzo impiego è simile al precedente e prevede l'uso di \func{bind}
all'interno dello stesso programma per associare indirizzi locali diversi a
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. Questo ovviamente non ha senso per il normale 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.
+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
In questo caso utilizzando \const{SO\_REUSEADDR} si consente ad una
applicazione eseguire \func{bind} sulla stessa porta ed indirizzo usata da
-un'altra, così che anche essa possa ricevere gli stessi pacchetti (chiaramente
-la cosa non ha alcun senso per i socket TCP, ed infatti in questo tipo di
-applicazione è normale l'uso del protocollo UDP). 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 è
+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
+\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}).
% 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
-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.
+\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
+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.
+
+\constend{SO\_REUSEPORT}
\constend{SO\_REUSEADDR}