%% sockctrl.tex
%%
-%% Copyright (C) 2004-2012 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2004-2015 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",
servizi di risoluzione dei nomi illustrati in sez.~\ref{sec:sock_resolver}; in
generale infatti ci sono una serie di funzioni nella forma
\texttt{getXXXbyname} e \texttt{getXXXbyaddr} (dove \texttt{XXX} indica il
-servizio) per ciascuna delle informazioni di rete mantenute dal
-\itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch} che permettono
-rispettivamente di trovare una corrispondenza cercando per nome o per numero.
+servizio) per ciascuna delle informazioni di rete mantenute dal \textit{Name
+ Service Switch} che permettono rispettivamente di trovare una corrispondenza
+cercando per nome o per numero.
L'elenco di queste funzioni è riportato nelle colonne finali di
tab.~\ref{tab:name_resolution_functions}, dove le si sono suddivise rispetto
al tipo di informazione che forniscono (riportato in prima colonna). Nella
tabella si è anche riportato il file su cui vengono ordinariamente mantenute
queste informazioni, che però può essere sostituito da un qualunque supporto
-interno al \itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch}
-(anche se usualmente questo avviene solo per la risoluzione degli indirizzi).
-Ciascuna funzione fa riferimento ad una sua apposita struttura che contiene i
-relativi dati, riportata in terza colonna.
+interno al \textit{Name Service Switch} (anche se usualmente questo avviene
+solo per la risoluzione degli indirizzi). Ciascuna funzione fa riferimento ad
+una sua apposita struttura che contiene i relativi dati, riportata in terza
+colonna.
\begin{table}[!htb]
\centering
\hline
\end{tabular}
\caption{Funzioni di risoluzione dei nomi per i vari servizi del
- \itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch}.}
+ \textit{Name Service Switch} riguardanti la rete.}
\label{tab:name_resolution_functions}
\end{table}
Delle funzioni di tab.~\ref{tab:name_resolution_functions} abbiamo trattato
finora soltanto quelle relative alla risoluzione dei nomi, dato che sono le
più usate, e prevedono praticamente da sempre la necessità di rivolgersi ad
-una entità esterna; per le altre invece, estensioni fornite dal
-\itindex{Name~Service~Switch~(NSS)} NSS a parte, si fa sempre riferimento ai
-dati mantenuti nei rispettivi file.
+una entità esterna; per le altre invece, estensioni fornite dal \textit{Name
+ Service Switch} a parte, si fa sempre riferimento ai dati mantenuti nei
+rispettivi file.
Dopo la risoluzione dei nomi a dominio una delle ricerche più comuni è quella
sui nomi dei servizi di rete più comuni (cioè \texttt{http}, \texttt{smtp},
Il primo argomento è il nome del servizio per \func{getservbyname},
specificato tramite la stringa \param{name}, mentre \func{getservbyport}
richiede il numero di porta in \param{port}. Entrambe le funzioni eseguono una
-ricerca sul file \conffile{/etc/services}\footnote{il
- \itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch} astrae il
- concetto a qualunque supporto su cui si possano mantenere i suddetti dati.}
-ed estraggono i dati dalla prima riga che corrisponde agli argomenti
-specificati; se la risoluzione ha successo viene restituito un puntatore ad
-una apposita struttura \struct{servent} contenente tutti i risultati,
-altrimenti viene restituito un puntatore nullo. Si tenga presente che anche
-in questo caso i dati vengono mantenuti in una area di memoria statica e che
-quindi la funzione non è \index{funzioni!rientranti} rientrante.
+ricerca sul file \conffile{/etc/services}\footnote{il \textit{Name Service
+ Switch} astrae il concetto a qualunque supporto su cui si possano
+ mantenere i suddetti dati.} ed estraggono i dati dalla prima riga che
+corrisponde agli argomenti specificati; se la risoluzione ha successo viene
+restituito un puntatore ad una apposita struttura \struct{servent} contenente
+tutti i risultati, altrimenti viene restituito un puntatore nullo. Si tenga
+presente che anche in questo caso i dati vengono mantenuti in una area di
+memoria statica e che quindi la funzione non è \index{funzioni!rientranti}
+rientrante.
\begin{figure}[!htb]
\footnotesize \centering
trovati nelle rispettive pagine di manuale.
Oltre alle funzioni di ricerca esistono delle ulteriori funzioni che prevedono
-una lettura sequenziale delle informazioni mantenute nel
-\itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch} (in sostanza
-permettono di leggere i file contenenti le informazioni riga per riga), che
-sono analoghe a quelle elencate in tab.~\ref{tab:sys_passwd_func} per le
-informazioni relative ai dati degli utenti e dei gruppi. Nel caso specifico
-dei servizi avremo allora le tre funzioni \funcd{setservent},
-\funcd{getservent} e \funcd{endservent} i cui prototipi sono:
+una lettura sequenziale delle informazioni mantenute nel \textit{Name Service
+ Switch} (in sostanza permettono di leggere i file contenenti le informazioni
+riga per riga), che sono analoghe a quelle elencate in
+tab.~\ref{tab:sys_passwd_func} per le informazioni relative ai dati degli
+utenti e dei gruppi. Nel caso specifico dei servizi avremo allora le tre
+funzioni \funcd{setservent}, \funcd{getservent} e \funcd{endservent} i cui
+prototipi sono:
\begin{functions}
\headdecl{netdb.h}
\funcdecl{void setservent(int stayopen)}
\hline
\end{tabular}
\caption{Funzioni lettura sequenziale dei dati del
- \itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch}.}
+ \textit{Name Service Switch}.}
\label{tab:name_sequential_read}
\end{table}
prima (\texttt{\small 6}) azzera il contenuto della struttura \var{hint} e poi
provvede (\texttt{\small 7--9}) ad inizializzarne i valori necessari per la
chiamata (\texttt{\small 10}) a \func{getaddrinfo}. Di quest'ultima si
-controlla (\texttt{\small 12-16}) il codice di ritorno, in modo da stampare un
+controlla (\texttt{\small 12--16}) il codice di ritorno, in modo da stampare un
avviso di errore, azzerare \var{errno} ed uscire in caso di errore. Dato che
ad una macchina possono corrispondere più indirizzi IP, e di tipo diverso (sia
IPv4 che IPv6), mentre il servizio può essere in ascolto soltanto su uno solo
di questi, si provvede a tentare la connessione per ciascun indirizzo
-restituito all'interno di un ciclo (\texttt{\small 18-40}) di scansione della
+restituito all'interno di un ciclo (\texttt{\small 18--40}) di scansione della
lista restituita da \func{getaddrinfo}, ma prima (\texttt{\small 17}) si salva
il valore del puntatore per poterlo riutilizzare alla fine per disallocare la
lista.
fallisce si controlla (\texttt{\small 20}) se sono disponibili altri
indirizzi, nel qual caso si passa al successivo (\texttt{\small 21}) e si
riprende (\texttt{\small 22}) il ciclo da capo; se non ve ne sono si stampa
-l'errore ritornando immediatamente (\texttt{\small 24-27}). Quando la
+l'errore ritornando immediatamente (\texttt{\small 24--27}). Quando la
creazione del socket ha avuto successo si procede (\texttt{\small 29})
direttamente con la connessione, di nuovo in caso di fallimento viene ripetuto
(\texttt{\small 30--38}) il controllo se vi sono o no altri indirizzi da
rispettiva struttura degli indirizzi.
Come già detto la funzione è analoga a \texttt{sockconn} ed inizia azzerando
-ed inizializzando (\texttt{\small 6-11}) opportunamente la struttura
+ed inizializzando (\texttt{\small 6--11}) opportunamente la struttura
\var{hint} con i valori ricevuti come argomenti, soltanto che in questo caso
si è usata (\texttt{\small 8}) una impostazione specifica dei flag di
\var{hint} usando \const{AI\_PASSIVE} per indicare che il socket sarà usato
-per una apertura passiva. Per il resto la chiamata (\texttt{\small 12-18}) a
+per una apertura passiva. Per il resto la chiamata (\texttt{\small 12--18}) a
\func{getaddrinfo} e ed il ciclo principale (\texttt{\small 20--42}) sono
identici, solo che si è sostituita (\texttt{\small 31}) la chiamata a
\func{connect} con una chiamata a \func{bind}. Anche la conclusione
\label{tab:sock_opt_socklevel}
\end{table}
+% 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 è
\item[\const{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
- di amministratore (in particolare con la \itindex{capabilities}
- \textit{capability} \const{CAP\_NET\_ADMIN}). L'opzione necessita inoltre
- dell'opportuno supporto nel kernel;\footnote{deve cioè essere definita la
- macro di preprocessore \macro{SOCK\_DEBUGGING} nel file
- \file{include/net/sock.h} dei sorgenti del kernel, questo è sempre vero
- nei kernel delle serie superiori alla 2.3, per i kernel delle serie
- precedenti invece è necessario aggiungere a mano detta definizione; è
- inoltre possibile abilitare anche il tracciamento degli stati del TCP
- definendo la macro \macro{STATE\_TRACE} in \file{include/net/tcp.h}.}
- quando viene abilitata una serie di messaggi con le informazioni di debug
- vengono inviati direttamente al sistema del kernel log.\footnote{si tenga
- presente che il comportamento è diverso da quanto avviene con BSD, dove
- l'opzione opera solo sui socket TCP, causando la scrittura di tutti i
- pacchetti inviati sulla rete su un buffer circolare che viene letto da un
- apposito programma, \cmd{trpt}.}
+ di amministratore (in particolare con la \textit{capability}
+ \const{CAP\_NET\_ADMIN}). L'opzione necessita inoltre dell'opportuno
+ supporto nel kernel;\footnote{deve cioè essere definita la macro di
+ preprocessore \macro{SOCK\_DEBUGGING} nel file \file{include/net/sock.h}
+ dei sorgenti del kernel, questo è sempre vero nei kernel delle serie
+ superiori alla 2.3, per i kernel delle serie precedenti invece è
+ necessario aggiungere a mano detta definizione; è inoltre possibile
+ abilitare anche il tracciamento degli stati del TCP definendo la macro
+ \macro{STATE\_TRACE} in \file{include/net/tcp.h}.} quando viene abilitata
+ una serie di messaggi con le informazioni di debug vengono inviati
+ direttamente al sistema del kernel log.\footnote{si tenga presente che il
+ comportamento è diverso da quanto avviene con BSD, dove l'opzione opera
+ solo sui socket TCP, causando la scrittura di tutti i pacchetti inviati
+ 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;
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 \itindex{capabilities} capability
- \const{CAP\_NET\_ADMIN}.
+ privilegi di amministratore con la capability \const{CAP\_NET\_ADMIN}.
\item[\const{SO\_ERROR}] questa opzione riceve un errore presente sul socket;
può essere utilizzata soltanto con \func{getsockopt} e prende per
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
-\func{setsockopt}. Si è poi aggiunta una sezione (\texttt{\small 13-17}) che
+\func{setsockopt}. Si è poi aggiunta una sezione (\texttt{\small 13--17}) che
esegue l'impostazione dell'opzione fra la chiamata a \func{socket} e quella a
\func{bind}.
valore di default di questa variabile è nullo, ma usando l'opzione \texttt{-r}
nell'invocazione del server (al solito la gestione delle opzioni non è
riportata in fig.~\ref{fig:TCP_echod_fifth}) se ne potrà impostare ad 1 il
-valore, per cui in tal caso la successiva chiamata (\texttt{\small 13-17}) a
+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]
\const{IP\_RECVERR} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
Abilita la gestione degli errori.\\
\const{IP\_MTU\_DISCOVER} &$\bullet$&$\bullet$& &\texttt{int}&
- Imposta il Path MTU \itindex{Maximum~Transfer~Unit~(MTU)} Discovery.\\
+ Imposta il \textit{Path MTU Discovery}.\\
\const{IP\_MTU} &$\bullet$& & &\texttt{int}&
Legge il valore attuale della \itindex{Maximum~Transfer~Unit~(MTU)} MTU.\\
\const{IP\_ROUTER\_ALERT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
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 \itindex{capabilities}
- capability \const{CAP\_NET\_ADMIN}.
+ richiedono i privilegi di amministrazione con la 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
come valore logico e non è applicabile a socket di tipo
\const{SOCK\_STREAM}.
-\itindbeg{Maximum~Transfer~Unit~(MTU)}
+\itindbeg{Path~MTU}
\item[\const{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
- \textit{Path Maximum Transfer Unit} (vedi sez.~\ref{sec:net_lim_dim}) del
+ \textit{Path MTU} (vedi sez.~\ref{sec:net_lim_dim}) del
socket. L'opzione prende per \param{optval} un valore intero che indica la
modalità usata, da specificare con una delle costanti riportate in
tab.~\ref{tab:sock_ip_mtu_discover}.
essere perduti, ed è compito dell'applicazione gestirne una eventuale
ritrasmissione.
-\itindend{Maximum~Transfer~Unit~(MTU)}
+\itindend{Path~MTU}
\item[\const{IP\_ROUTER\_ALERT}] Questa è una opzione introdotta con i
kernel della serie 2.2.x, ed è specifica di Linux. Prende per
\const{TCP\_DEFER\_ACCEPT}&$\bullet$&$\bullet$& &\texttt{int}&
Ritorna da \func{accept} solo in presenza di dati.\\
\const{TCP\_WINDOW\_CLAMP}&$\bullet$&$\bullet$& &\texttt{int}&
- Valore della \itindex{advertised~window} \textit{advertised window}.\\
+ Valore della \textit{advertised window}.\\
\const{TCP\_INFO} &$\bullet$& & &\struct{tcp\_info}&
Restituisce informazioni sul socket.\\
\const{TCP\_QUICKACK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
\item[\const{TCP\_WINDOW\_CLAMP}] con questa opzione si legge o si imposta
alla dimensione specificata, in byte, il valore dichiarato della
- \itindex{advertised~window} \textit{advertised window} (vedi
- sez.~\ref{sec:tcp_protocol_xxx}). Il kernel impone comunque una dimensione
- minima pari a \texttt{SOCK\_MIN\_RCVBUF/2}. Questa opzione non deve essere
- utilizzata in codice che vuole essere portabile.
+ \textit{advertised window} (vedi sez.~\ref{sec:tcp_protocol_xxx}). Il kernel
+ impone comunque una dimensione minima pari a \texttt{SOCK\_MIN\_RCVBUF/2}.
+ Questa opzione non deve essere utilizzata in codice che vuole essere
+ portabile.
\begin{figure}[!htb]
\footnotesize \centering
Si tenga inoltre presente che alcune di queste operazioni (in particolare
quelle che modificano le caratteristiche dell'interfaccia) sono privilegiate e
-richiedono i privilegi di amministratore o la \itindex{capabilities}
-\textit{capability} \const{CAP\_NET\_ADMIN}, altrimenti si otterrà un errore
-di \errval{EPERM}. Le costanti che identificano le operazioni disponibili
-sono le seguenti:
+richiedono i privilegi di amministratore o la \textit{capability}
+\const{CAP\_NET\_ADMIN}, altrimenti si otterrà un errore di \errval{EPERM}.
+Le costanti che identificano le operazioni disponibili sono le seguenti:
\begin{basedescript}{\desclabelwidth{2.7cm}\desclabelstyle{\nextlinelabel}}
\item[\const{SIOCGIFNAME}] questa è l'unica operazione che usa il campo
\var{ifr\_name} per restituire un risultato, tutte le altre lo utilizzano
\end{basedescript}
+
+% TODO aggiunta con il kernel 3.14 SIOCGHWTSTAMP per ottenere il timestamp
+% hardware senza modificarlo
+
Una ulteriore operazione, che consente di ricavare le caratteristiche delle
interfacce di rete, è \const{SIOCGIFCONF}; però per ragioni di compatibilità
questa operazione è disponibile soltanto per i socket della famiglia
nel file \texttt{Documentation/networking/ip-sysctl.txt}; la maggior parte di
questi però non è documentato:
\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\sysctlrelfile{net/core}{dev\_weight}] blocco di lavoro
- (\textit{work quantum}) dello scheduler di processo dei pacchetti.
+\item[\sysctlrelfile{net/core}{dev\_weight}] blocco di lavoro (\textit{work
+ quantum}) dello \textit{scheduler} di processo dei pacchetti.
% TODO da documentare meglio
valore iniziale maggiore di 1024 (o meglio ancora di 4096) per evitare
conflitti con le porte usate dai servizi noti.
-\item[\sysctlrelfile{net/ipv4}{ip\_no\_pmtu\_disc}] permette di
- disabilitare per i socket \const{SOCK\_STREAM} la ricerca automatica della
- \itindex{Maximum~Transfer~Unit~(MTU)} \textit{Path MTU} (vedi
- sez.~\ref{sec:net_lim_dim} e sez.~\ref{sec:sock_ipv4_options}). Prende un
- valore logico, e di default è disabilitato (cioè la ricerca viene eseguita).
+\item[\sysctlrelfile{net/ipv4}{ip\_no\_pmtu\_disc}] permette di disabilitare
+ per i socket \const{SOCK\_STREAM} la ricerca automatica della \textit{Path
+ MTU} (vedi sez.~\ref{sec:net_lim_dim} e
+ sez.~\ref{sec:sock_ipv4_options}). Prende un valore logico, e di default è
+ disabilitato (cioè la ricerca viene eseguita).
In genere si abilita questo parametro quando per qualche motivo il
- procedimento del \itindex{Maximum~Transfer~Unit~(MTU)} \textit{Path MTU
- discovery} fallisce; dato che questo può avvenire a causa di
- router\footnote{ad esempio se si scartano tutti i pacchetti ICMP, il
- problema è affrontato anche in sez.~3.4.4 di \cite{SGL}.} o
- interfacce\footnote{ad esempio se i due capi di un collegamento
- \textit{point-to-point} non si accordano sulla stessa MTU.} mal
- configurati è opportuno correggere le configurazioni, perché disabilitare
- globalmente il procedimento con questo parametro ha pesanti ripercussioni in
- termini di prestazioni di rete.
+ procedimento del \textit{Path MTU discovery} fallisce; dato che questo può
+ avvenire a causa di router\footnote{ad esempio se si scartano tutti i
+ pacchetti ICMP, il problema è affrontato anche in sez.~3.4.4 di
+ \cite{SGL}.} o interfacce\footnote{ad esempio se i due capi di un
+ collegamento \textit{point-to-point} non si accordano sulla stessa MTU.}
+ mal configurati è opportuno correggere le configurazioni, perché
+ disabilitare globalmente il procedimento con questo parametro ha pesanti
+ ripercussioni in termini di prestazioni di rete.
\item[\sysctlrelfile{net/ipv4}{ip\_always\_defrag}] fa si che tutti i
pacchetti IP frammentati siano riassemblati, anche in caso in successivo
quando si è sicuri che non è possibile ottimizzare il server in modo che sia
in grado di accettare connessioni più rapidamente.
-\item[\sysctlrelfile{net/ipv4}{tcp\_adv\_win\_scale}] indica al kernel
- quale frazione del buffer associato ad un socket\footnote{quello impostato
- con \sysctlrelfile{net/ipv4}{tcp\_rmem}.} deve essere utilizzata
- per la finestra del protocollo TCP\footnote{in sostanza il valore che
- costituisce la \itindex{advertised~window} \textit{advertised window}
- annunciata all'altro capo del socket.} e quale come buffer applicativo per
- isolare la rete dalle latenze dell'applicazione. Prende un valore intero
- che determina la suddetta frazione secondo la formula
+\item[\sysctlrelfile{net/ipv4}{tcp\_adv\_win\_scale}] indica al kernel quale
+ frazione del buffer associato ad un socket\footnote{quello impostato con
+ \sysctlrelfile{net/ipv4}{tcp\_rmem}.} deve essere utilizzata per la
+ finestra del protocollo TCP\footnote{in sostanza il valore che costituisce
+ la \textit{advertised window} annunciata all'altro capo del socket.} e
+ quale come buffer applicativo per isolare la rete dalle latenze
+ dell'applicazione. Prende un valore intero che determina la suddetta
+ frazione secondo la formula
$\texttt{buffer}/2^\texttt{tcp\_adv\_win\_scale}$ se positivo o con
$\texttt{buffer}-\texttt{buffer}/2^\texttt{tcp\_adv\_win\_scale}$ se
negativo. Il default è 2 che significa che al buffer dell'applicazione