%% sockctrl.tex
%%
-%% Copyright (C) 2004-2017 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2004-2018 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Prefazione",
indirizzi generiche, questo sia ancora di tipo \texttt{char **} e si possa
riutilizzare lo stesso puntatore usato per i nomi.
-Per ciascun indirizzo valido si provvederà (\texttt{\small 41}) ad una
+Per ciascun indirizzo valido si provvederà (\texttt{\small 41}) a una
conversione con la funzione \func{inet\_ntop} (vedi
sez.~\ref{sec:sock_addr_func}) passandole gli opportuni argomenti, questa
restituirà la stringa da stampare (\texttt{\small 42}) con il valore
\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{AF\_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
\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.
+ 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
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}
specificare come argomento per questa opzione sono impostabili tramiti gli
opportuni valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
- Si tenga presente che nel caso di socket TCP, per entrambe le opzioni
- \const{SO\_RCVBUF} e \const{SO\_SNDBUF}, il kernel alloca effettivamente una
- quantità di memoria doppia rispetto a quanto richiesto con
- \func{setsockopt}. Questo comporta che una successiva lettura con
+ Si tenga presente che nel caso di socket TCP il kernel alloca effettivamente
+ una quantità di memoria doppia rispetto a quanto richiesto con
+ \func{setsockopt} per entrambe le opzioni \const{SO\_RCVBUF} e
+ \const{SO\_SNDBUF}. Questo comporta che una successiva lettura con
\func{getsockopt} riporterà un valore diverso da quello impostato con
\func{setsockopt}. Questo avviene perché TCP necessita dello spazio in più
per mantenere dati amministrativi e strutture interne, e solo una parte
\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
+ amministratore (per la precisione con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}) di impostare in valore maggiore del limite di
\sysctlrelfile{net/core}{rmem\_max}.
\item[\constd{SO\_RCVLOWAT}] questa opzione imposta il valore che indica il
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.
+ cambiato solo con i kernel a partire dal 2.4. Si tenga presente però che per
+ i kernel prima del 2.6.28 sia \func{poll} che \func{select} non supportano
+ questa funzionalità e ritornano comunque, indicando il socket come
+ leggibile, non appena almeno un byte è presente, con una successiva lettura
+ con \func{read} che si blocca fintanto che non diventa disponibile 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\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
sulle operazioni di lettura da un socket, e prende per \param{optval} una
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
\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
+ amministratore (per la precisione 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
\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\_REUSEPORT}}
-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}).
-
-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ò
-ricordare (si riveda quanto detto in sez.~\ref{sec:TCP_time_wait}) che la
-presenza dello stato \texttt{TIME\_WAIT} ha una ragione, ed infatti se si usa
-questa opzione esiste sempre una probabilità, anche se estremamente
-remota,\footnote{perché ciò avvenga infatti non solo devono coincidere gli
- indirizzi IP e le porte degli estremi della nuova connessione, ma anche i
- numeri di sequenza dei pacchetti, e questo è estremamente improbabile.} che
-eventuali pacchetti rimasti intrappolati in una precedente connessione possano
-finire fra quelli di una nuova.
+ 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}).
\begin{figure}[!htbp]
\footnotesize \centering
\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ò
+ricordare (si riveda quanto detto in sez.~\ref{sec:TCP_time_wait}) che la
+presenza dello stato \texttt{TIME\_WAIT} ha una ragione, ed infatti se si usa
+questa opzione esiste sempre una probabilità, anche se estremamente
+remota,\footnote{perché ciò avvenga infatti non solo devono coincidere gli
+ indirizzi IP e le porte degli estremi della nuova connessione, ma anche i
+ numeri di sequenza dei pacchetti, e questo è estremamente improbabile.} che
+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})
\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}
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.
-
-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 (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
+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 è
+\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ò 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 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}
\begin{table}[!htb]
\centering
\footnotesize
- \begin{tabular}[c]{|l|c|c|c|l|p{5.cm}|}
+ \begin{tabular}[c]{|l|c|c|c|l|p{4.8cm}|}
\hline
\textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
\textbf{Descrizione}\\
\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}.}
+ \caption{Le opzioni disponibili al livello \const{IPPROTO\_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.90\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 per unirsi a un gruppo di
+ \textit{multicast}.}
+ \label{fig:ip_mreqn_struct}
\end{figure}
+Questa struttura è presente a partire dal kernel 2.2, per compatibilità è
+possibile utilizzare anche un argomento di tipo \struct{ip\_mreq}, presente
+fino dal kernel 1.2, che differisce da essa soltanto per l'assenza del campo
+\var{imr\_ifindex}; il kernel riconosce il tipo di struttura in base alla
+differente dimensione passata in \param{optlen}.
-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}).
+\item[\constd{IP\_ADD\_SOURCE\_MEMBERSHIP}] L'opzione consente di unirsi ad
+ gruppo di \textit{multicast}, ricevendo i dati solo da una sorgente
+ specifica; come \const{IP\_ADD\_MEMBERSHIP} può essere usata solo con
+ \func{setsockopt}.
-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}).
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.90\textwidth}
+ \includestruct{listati/ip_mreq_source.h}
+ \end{minipage}
+ \caption{La struttura \structd{ip\_mreqn} utilizzata per unirsi a un gruppo di
+ \textit{multicast} per una specifica sorgente.}
+ \label{fig:ip_mreq_source_struct}
+\end{figure}
+L'argomento \param{optval} in questo caso è una struttura
+\struct{ip\_mreq\_source} illustrata in fig.~\ref{fig:ip_mreq_source_struct},
+dove il campo \var{imr\_multiaddr} è l'indirizzo del gruppo di
+\textit{multicast}, il campo \var{imr\_interface} l'indirizzo dell'interfaccia
+locale che deve essere usata per aggiungersi al gruppo di \textit{multicast} e
+il campo \var{imr\_sourceaddr} l'indirizzo della sorgente da cui
+l'applicazione vuole ricevere i dati. L'opzione può essere ripetuta più volte
+per collegarsi a diverse sorgenti.
+
+\item[\constd{IP\_BLOCK\_SOURCE}] Questa opzione, disponibile dal kernel
+ 2.4.22, consente di smettere di ricevere dati di \textit{multicast} dalla
+ sorgente (e relativo gruppo) specificati dalla struttura
+ \struct{ip\_mreq\_source} (vedi fig.~\ref{fig:ip_mreq_source_struct})
+ passata come argomento \param{optval}. L'opzione è utilizzabile solo se si è
+ già registrati nel gruppo di \textit{multicast} indicato con un precedente
+ utilizzo di \const{IP\_ADD\_MEMBERSHIP} o
+ \const{IP\_ADD\_SOURCE\_MEMBERSHIP}.
-\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
+\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 per \const{IP\_ADD\_MEMBERSHIP} (vedi
+ fig.~\ref{fig:ip_mreqn_struct}).
+
+\item[\constd{IP\_DROP\_SOURCE\_MEMBERSHIP}] Lascia un gruppo di
+ \textit{multicast} per una specifica sorgente, prende per \param{optval} la
+ stessa struttura \struct{ip\_mreq\_source} usata per
+ \const{IP\_ADD\_SOURCE\_MEMBERSHIP} (vedi
+ fig.~\ref{fig:ip_mreq_source_struct}). Se ci si è registrati per più
+ sorgenti nello stesso gruppo, si continuerà a ricevere dati sulle altre. Per
+ smettere di ricevere dati da tutte le sorgenti occorre usare l'opzione
+ \const{IP\_LEAVE\_GROUP}.
+
+\item[\constd{IP\_FREEBIND}] Se abilitata questa opzione, disponibile dal
+ kernel 2.4, consente di usare \func{bind} anche su un indirizzo IP non
+ locale o che ancora non è stato assegnato. Questo permette ad una
+ applicazione di mettersi in ascolto su un socket prima che l'interfaccia
+ sottostante o l'indirizzo che questa deve usare sia stato configurato. È
+ l'equivalente a livello di singolo socket dell'uso della \textit{sysctl}
+ \texttt{ip\_nonlocal\_bind} che vedremo in
+ sez.~\ref{sec:sock_ipv4_sysctl}. 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\_HDRINCL}] Se viene abilitata questa opzione, presente dal
+ kernel 2.0, l'utente deve fornire lui stesso l'intestazione del protocollo
+ IP in testa 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}. Prende per \param{optval} un intero usato come
+ valore logico.
+
+\item[\constd{IP\_MSFILTER}] L'opzione, introdotta con il kernel 2.4.22,
+ fornisce accesso completo all'interfaccia per il filtraggio delle sorgenti
+ di \textit{multicast} (il cosiddetto \textit{multicast source filtering},
+ definito dall'\href{http://www.ietf.org/rfc/rfc3376.txt}{RFC~3376}).
-\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\_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}.
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.90\textwidth}
+ \includestruct{listati/ip_msfilter.h}
+ \end{minipage}
+ \caption{La struttura \structd{ip\_msfilter} utilizzata per il
+ \textit{multicast source filtering}.}
+ \label{fig:ip_msfilter_struct}
+\end{figure}
-\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.
+L'argomento \param{optval} deve essere una struttura di tipo
+\struct{ip\_msfilter} (illustrata in fig.~\ref{fig:ip_msfilter_struct}); il
+campo \var{imsf\_multiaddr} indica l'indirizzo del gruppo di
+\textit{multicast}, il campo \var{imsf\_interface} l'indirizzo
+dell'interfaccia locale, il campo \var{imsf\_mode} indica la modalità di
+filtraggio e con i campi \var{imsf\_numsrc} e \var{imsf\_slist}
+rispettivamente la lunghezza della lista, e la lista stessa, degli indirizzi
+sorgente.
+
+Come ausilio all'uso di questa opzione sono disponibili le macro
+\macro{MCAST\_INCLUDE} e \macro{MCAST\_EXCLUDE} che si possono usare per
+\var{imsf\_mode}. Inoltre si può usare la macro
+\macro{IP\_MSFILTER\_SIZE}\texttt{(\textsf{n})} per determinare il valore
+di \param{optlen} con una struttura \struct{ip\_msfilter} contenente
+\texttt{\textsf{n}} sorgenti in \var{imsf\_slist}.
\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
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}
+ 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 può 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
\constd{IP\_PMTUDISC\_DO} &2& Esegue la procedura di determinazione
della \textit{Path MTU} come richiesto
dall'\href{http://www.ietf.org/rfc/rfc1191.txt}{RFC~1191}.\\
+ \constd{IP\_PMTUDISC\_PROBE}&?& .\\
\hline
\end{tabular}
\caption{Valori possibili per l'argomento \param{optval} di
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
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}
+
+\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}.
- 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\_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}
dati ancillari e di controllo (vedi sez.~\ref{sec:net_ancillary_data}).
\end{basedescript}
-Oltre a questi nella directory \texttt{/proc/sys/net/core} si trovano altri
-file, la cui documentazione dovrebbe essere mantenuta nei sorgenti del kernel,
-nel file \texttt{Documentation/networking/ip-sysctl.txt}; la maggior parte di
-questi però non è documentato:
+Oltre a questi, nella directory \texttt{/proc/sys/net/core} si trovano diversi
+altri file, la cui documentazione, come per gli altri, dovrebbe essere
+mantenuta nei sorgenti del kernel nel file
+\texttt{Documentation/networking/ip-sysctl.txt}; la maggior parte di questi
+però non è documentato:
\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
\item[\sysctlrelfiled{net/core}{dev\_weight}] blocco di lavoro (\textit{work
quantum}) dello \textit{scheduler} di processo dei pacchetti.
\item[\sysctlrelfiled{net/ipv4}{ipfrag\_high\_thresh}] indica il limite
massimo (espresso in numero di byte) sui pacchetti IP frammentati presenti
- in coda; quando questo valore viene raggiunta la coda viene ripulita fino al
+ in coda; quando questo valore viene raggiunto la coda viene ripulita fino al
valore \texttt{ipfrag\_low\_thresh}. Prende un valore intero.
-\item[\sysctlrelfiled{net/ipv4}{ipfrag\_low\_thresh}] soglia bassa
- (specificata in byte) a cui viene riportata la coda dei pacchetti IP
- frammentati quando si raggiunge il valore massimo dato da
+\item[\sysctlrelfiled{net/ipv4}{ipfrag\_low\_thresh}] indica la dimensione
+ (specificata in byte) della soglia inferiore a cui viene riportata la coda
+ dei pacchetti IP frammentati quando si raggiunge il valore massimo dato da
\texttt{ipfrag\_high\_thresh}. Prende un valore intero.
\item[\sysctlrelfiled{net/ipv4}{ip\_nonlocal\_bind}] se abilitato rende
possibile ad una applicazione eseguire \func{bind} anche su un indirizzo che
non è presente su nessuna interfaccia locale. Prende un valore logico e di
- default è disabilitato.
+ default è disabilitato. La funzionalità può essere abilitata a livello di
+ singolo socket con l'opzione \const{IP\_FREEBIND} illustrata in
+ sez.~\ref{sec:sock_ipv4_options}.
Questo può risultare utile per applicazioni particolari (come gli
\textit{sniffer}) che hanno la necessità di ricevere pacchetti anche non
\item il secondo valore, denominato \textit{default}, indica la dimensione
di default in byte del buffer di spedizione di un socket TCP. Questo
valore sovrascrive il default iniziale impostato per tutti i tipi di
- socket con \sysctlfile{net/core/wmem\_default}. Il default è 87380 byte,
- ridotto a 43689 per sistemi con poca memoria. Si può aumentare questo
- valore quando si desiderano dimensioni più ampie del buffer di
+ socket sul file \sysctlfile{net/core/wmem\_default}. Il default è 87380
+ byte, ridotto a 43689 per sistemi con poca memoria. Si può aumentare
+ questo valore quando si desiderano dimensioni più ampie del buffer di
trasmissione per i socket TCP, ma come per il precedente
\sysctlrelfile{net/ipv4}{tcp\_rmem}) se si vuole che in corrispondenza
aumentino anche le dimensioni usate per la finestra TCP si deve abilitare