%% sockctrl.tex
%%
-%% Copyright (C) 2004-2006 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2004-2007 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",
%% license is included in the section entitled "GNU Free Documentation
%% License".
%%
+
\chapter{La gestione dei socket}
\label{cha:sock_generic_management}
\subsection{La risoluzione dei nomi a dominio}
\label{sec:sock_name_services}
-La principale funzionalità del \itindex{resolver}\textit{resolver} resta
+La principale funzionalità del \itindex{resolver} \textit{resolver} resta
quella di risolvere i nomi a dominio in indirizzi IP, per cui non ci
dedicheremo oltre alle funzioni di richiesta generica ed esamineremo invece le
funzioni a questo dedicate. La prima funzione è \funcd{gethostbyname} il cui
IPv4, se si vogliono ottenere degli indirizzi IPv6 occorrerà prima impostare
l'opzione \const{RES\_USE\_INET6} nel campo \texttt{\_res.options} e poi
chiamare \func{res\_init} (vedi sez.~\ref{sec:sock_resolver_functions}) per
-modificare le opzioni del \itindex{resolver}\textit{resolver}; dato che
+modificare le opzioni del \itindex{resolver} \textit{resolver}; dato che
questo non è molto comodo è stata definita\footnote{questa è una estensione
fornita dalle \acr{glibc}, disponibile anche in altri sistemi unix-like.}
un'altra funzione, \funcd{gethostbyname2}, il cui prototipo è:
Vediamo allora un primo esempio dell'uso delle funzioni di risoluzione, in
fig.~\ref{fig:mygethost_example} è riportato un estratto del codice di un
programma che esegue una semplice interrogazione al
-\itindex{resolver}\textit{resolver} usando \func{gethostbyname} e poi ne
+\itindex{resolver} \textit{resolver} usando \func{gethostbyname} e poi ne
stampa a video i risultati. Al solito il sorgente completo, che comprende il
trattamento delle opzioni ed una funzione per stampare un messaggio di aiuto,
è nel file \texttt{mygethost.c} dei sorgenti allegati alla guida.
copiare il contenuto della sola struttura non è sufficiente per salvare tutti
i dati, in quanto questa contiene puntatori ad altri dati, che pure possono
essere sovrascritti; per questo motivo, se si vuole salvare il risultato di
-una chiamata, occorrerà eseguire quella che si chiama una
-\itindex{deep~copy}\textit{deep copy}.\footnote{si chiama così quella tecnica
- per cui, quando si deve copiare il contenuto di una struttura complessa (con
- puntatori che puntano ad altri dati, che a loro volta possono essere
- puntatori ad altri dati) si deve copiare non solo il contenuto della
- struttura, ma eseguire una scansione per risolvere anche tutti i puntatori
- contenuti in essa (e così via se vi sono altre sottostrutture con altri
- puntatori) e copiare anche i dati da questi referenziati.}
+una chiamata, occorrerà eseguire quella che si chiama una \itindex{deep~copy}
+\textit{deep copy}.\footnote{si chiama così quella tecnica per cui, quando si
+ deve copiare il contenuto di una struttura complessa (con puntatori che
+ puntano ad altri dati, che a loro volta possono essere puntatori ad altri
+ dati) si deve copiare non solo il contenuto della struttura, ma eseguire una
+ scansione per risolvere anche tutti i puntatori contenuti in essa (e così
+ via se vi sono altre sottostrutture con altri puntatori) e copiare anche i
+ dati da questi referenziati.}
Per ovviare a questi problemi nelle \acr{glibc} sono definite anche delle
versioni rientranti delle precedenti funzioni, al solito queste sono
\param{buf} e \param{buflen}.
Gli ultimi due argomenti vengono utilizzati per avere indietro i risultati
-come \itindex{value~result~argument}\textit{value result argument}, si deve
+come \itindex{value~result~argument} \textit{value result argument}, si deve
specificare l'indirizzo della variabile su cui la funzione dovrà salvare il
codice di errore con \param{h\_errnop} e quello su cui dovrà salvare il
puntatore che si userà per accedere i dati con \param{result}.
rientrante, ed alloca autonomamente tutta la memoria necessaria in cui
verranno riportati i risultati della risoluzione. La funzione scriverà
all'indirizzo puntato da \param{res} il puntatore iniziale ad una
-\itindex{linked~list}\textit{linked list} di strutture di tipo
+\itindex{linked~list} \textit{linked list} di strutture di tipo
\struct{addrinfo} contenenti tutte le informazioni ottenute.
\begin{figure}[!htb]
\begin{figure}[!htb]
\centering
\includegraphics[width=10cm]{img/addrinfo_list}
- \caption{La \itindex{linked~list}\textit{linked list} delle strutture
+ \caption{La \itindex{linked~list} \textit{linked list} delle strutture
\struct{addrinfo} restituite da \func{getaddrinfo}.}
\label{fig:sock_addrinfo_list}
\end{figure}
Come primo esempio di uso di \func{getaddrinfo} vediamo un programma
-elementare di interrogazione del \itindex{resolver}\textit{resolver} basato
+elementare di interrogazione del \itindex{resolver} \textit{resolver} basato
questa funzione, il cui corpo principale è riportato in
fig.~\ref{fig:mygetaddr_example}. Il codice completo del programma, compresa
la gestione delle opzioni in cui è gestita l'eventuale inizializzazione
\end{Verbatim}
%$
-Una volta estratti i risultati dalla \itindex{linked~list}\textit{linked list}
+Una volta estratti i risultati dalla \itindex{linked~list} \textit{linked list}
puntata da \param{res} se questa non viene più utilizzata si dovrà avere cura
di disallocare opportunamente tutta la memoria, per questo viene fornita
l'apposita funzione \funcd{freeaddrinfo}, il cui prototipo è:
Si tenga presente infine che se si copiano i risultati da una delle strutture
\struct{addrinfo} restituite nella lista indicizzata da \param{res}, occorre
-avere cura di eseguire una \itindex{deep~copy}\textit{deep copy} in cui
+avere cura di eseguire una \itindex{deep~copy} \textit{deep copy} in cui
si copiano anche tutti i dati presenti agli indirizzi contenuti nella
struttura \struct{addrinfo}, perché una volta disallocati i dati con
\func{freeaddrinfo} questi non sarebbero più disponibili.
per entrambe le funzioni. In questo caso \param{optval} viene usato per
ricevere le informazioni ed indica l'indirizzo a cui andranno scritti i dati
letti dal socket, infine \param{optlen} diventa un puntatore ad una variabile
-che viene usata come \itindex{value~result~argument}\textit{value result
+che viene usata come \itindex{value~result~argument} \textit{value result
argument} per indicare, prima della chiamata della funzione, la lunghezza
del buffer allocato per \param{optval} e per ricevere indietro, dopo la
chiamata della funzione, la dimensione effettiva dei dati scritti su di esso.
connessione si sia ristabilita e si riceva un successivo messaggio di risposta
il ciclo riparte come se niente fosse avvenuto. Infine se si riceve come
risposta un pacchetto ICMP di destinazione irraggiungibile (vedi
-sez.~\ref{sec:icmp_protocol_xxx}), verrà restituito l'errore corrispondente.
+sez.~\ref{sec:ICMP_protocol}), verrà restituito l'errore corrispondente.
In generale questa opzione serve per individuare una caduta della connessione
anche quando non si sta facendo traffico su di essa. Viene usata
dell'interfaccia, e restituisce il relativo nome in \var{ifr\_name}.
Il kernel infatti assegna ad ogni interfaccia un numero progressivo, detto
- appunto \index{interface index} \textit{interface index}, che è quello che
+ appunto \itindex{interface~index} \textit{interface index}, che è quello che
effettivamente la identifica nelle operazioni a basso livello, il nome
dell'interfaccia è soltanto una etichetta associata a detto \textsl{indice},
che permette di rendere più comprensibile l'indicazione dell'interfaccia
questi però non è documentato:
\begin{basedescript}{\desclabelwidth{3.0cm}\desclabelstyle{\nextlinelabel}}
\item[\texttt{dev\_weight}] blocco di lavoro (\textit{work quantum}) dello
- scheduler di processo dei pacchetti. % TODO da documentare meglio
+ scheduler di processo dei pacchetti.
+
+% TODO da documentare meglio
\item[\texttt{lo\_cong}] valore per l'occupazione della coda di ricezione
sotto la quale si considera di avere una bassa congestione.
\begin{basedescript}{\desclabelwidth{3.5cm}\desclabelstyle{\nextlinelabel}}
\item[\texttt{ip\_default\_ttl}] imposta il valore di default per il campo TTL
- (vedi sez.~\ref{sec:IP_header}) di tutti i pacchetti uscenti. Il valore può
- essere modificato per il singolo socket con l'opzione \const{IP\_TTL}.
- Prende un valore intero.
+ (vedi sez.~\ref{sec:IP_header}) di tutti i pacchetti uscenti, stabilendo
+ così il numero massimo di router che i pacchetti possono attraversare. Il
+ valore può essere modificato anche per il singolo socket con l'opzione
+ \const{IP\_TTL}. Prende un valore intero, ma dato che il campo citato è di
+ 8 bit hanno senso solo valori fra 0 e 255. Il valore di default è 64, e non
+ ci normalmente non c'è nessuna necessità di modificarlo,\footnote{l'unico
+ motivo sarebbe per raggiungere macchine estremamente ``{lontane}'' in
+ termini di \textit{hop}, ma è praticamente } aumentare il valore è una
+ pratica poco gentile, in quanto in caso di problemi di routing si allunga
+ inutilmente il numero di ritrasmissioni.
+
\item[\texttt{ip\_forward}] abilita l'inoltro dei pacchetti da una interfaccia
ad un altra, e può essere impostato anche per la singola interfaccia. Prende
caratteristiche specifiche del protocollo TCP, elencati anche nella rispettiva
pagina di manuale (accessibile con \texttt{man 7 tcp}), sono i seguenti:
\begin{basedescript}{\desclabelwidth{3.9cm}\desclabelstyle{\nextlinelabel}}
-\item[\texttt{tcp\_abort\_on\_overflow}]
-\item[\texttt{tcp\_adv\_win\_scale}]
-\item[\texttt{tcp\_app\_win}]
-\item[\texttt{tcp\_bic\_low\_window}]
-\item[\texttt{tcp\_bic\_fast\_convergence}]
-\item[\texttt{tcp\_dsack}]
-\item[\texttt{tcp\_ecn}]
-\item[\texttt{tcp\_fack}]
+
+\item[\texttt{tcp\_abort\_on\_overflow}] è un valore logico (disabilitato di
+ default) che indica di azzerare le connessioni quando il programma che le
+ riceve è troppo lento ed incapace di accettarle. Questo consente di
+ recuperare le connessioni se si è avuto un eccesso dovuto ad un qualche
+ picco di traffico, ma ovviamente va a discapito dei client che interrogano
+ il server. Pertanto è da abilitare soltanto quando si è sicuri che non è
+ possibile ottimizzare il server in modo che sia in grado di accettare
+ connessioni più rapidamente.
+
+\item[\texttt{tcp\_adv\_win\_scale}] questa variabile intera indica al kernel
+ quanto spazio all'interno del buffer associato ad un socket (quello
+ impostato con \texttt{tcp\_rmem}) deve essere utilizzato per la finestra del
+ protocollo TCP (quello che costituisce la \itindex{advertised~window}
+ \textit{advertised window} annunciata all'altro capo del socket) e quello
+ che viene usato come buffer applicativo per isolare la rete dalle latenze
+ dell'applicazione. Il valore viene calcolato 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 valore di default è 2 che significa che al buffer
+ dell'applicazione viene riservato un quarto del totale.
+
+\item[\texttt{tcp\_app\_win}] il valore indica quanti byte della finestra TCP
+ vengono riservati per la bufferizzazione, valore è il massimo fra la
+ \itindex{Maximum~Segment~Size} MSS e
+ $\texttt{window}/2^\texttt{tcp\_app\_win}$. Un valore nullo significa che
+ non viene riservato nessuno spazio; il default è 31.
+
+% vecchi, presumibilmente usati quando gli algoritmi di congestione non erano
+% modularizzabili
+% \item[\texttt{tcp\_bic}]
+% \item[\texttt{tcp\_bic\_low\_window}]
+% \item[\texttt{tcp\_bic\_fast\_convergence}]
+
+\item[\texttt{tcp\_dsack}] Abilita il supporto definito
+ nell'\href{http://www.ietf.org/rfc/rfc2884.txt}{RFC~2884} per il
+ \textit{Duplicate SACK}.\footnote{si indica con SACK (\textit{Selective
+ Acknowledgement}) un'opzione TCP, definita
+ nell'\href{http://www.ietf.org/rfc/rfc2018.txt}{RFC~2018}, usata per dare
+ un \textit{acknowledgement} unico su blocchi di pacchetti non contigui.}
+
+\item[\texttt{tcp\_ecn}] Abilita il meccanismo della \textit{Explicit
+ Congestion Notification} (o ECN) definito
+ nell'\href{http://www.ietf.org/rfc/rfc2884.txt}{RFC~2884}. Si tenga presente
+ che se si abilita questa opzione si possono avere dei malfunzionamenti
+ apparentemente casuali dipendenti dalla destinazione, dovuti al fatto che
+ alcuni vecchi router non supportano il meccanismo ed alla sua attivazione
+ scartano i relativi pacchetti.\\
+
+\item[\texttt{tcp\_fack}] è un valore logico che abilita il supporto per il
+ \textit{TCP Forward Acknowledgement}. Di default è abilitato.
+% TODO documentare o descrivere che cos'è il TCP Forward Acknowledgement
\item[\texttt{tcp\_fin\_timeout}] specifica il numero di secondi (il default è
60\footnote{nei kernel della serie 2.2.x era invece di 120 secondi.}) da
alcuni attacchi di \itindex{Denial~of~Service~(DoS)} \textit{Denial of
Service}.
-
-\item[\texttt{tcp\_frto}]
-\item[\texttt{tcp\_keepalive\_intvl}]
-\item[\texttt{tcp\_keepalive\_probes}]
-\item[\texttt{tcp\_keepalive\_time}]
-\item[\texttt{tcp\_low\_latency}]
-\item[\texttt{tcp\_max\_orphans}]
+\item[\texttt{tcp\_frto}] è un valore logico che abilita il supporto per
+ l'algoritmo F-RTO, un algoritmo usato per la ritrasmissione dei timeout del
+ protocollo TCP, che diventa molto utile per le reti wireless dove la perdita
+ di pacchetti è usualmente dovuta a delle interferenze radio, piuttosto che
+ alla congestione dei router. Di default è disabilitato.
+
+
+\item[\texttt{tcp\_keepalive\_intvl}] il numero di secondi che deve
+ trascorrere fra l'emissione di due successivi pacchetti di test quando è
+ abilitata la funzionalità del \textit{keepalive} (vedi
+ sez.~\ref{sec:sock_options_main}). Il valore di default è 75.
+
+\item[\texttt{tcp\_keepalive\_probes}] il massimo numero pacchetti di
+ \textit{keepalive} (vedi sez.~\ref{sec:sock_options_main}) che devono essere
+ inviati senza ricevere risposta prima che il kernel decida che la
+ connessione è caduta e la termini. Il valore di default è 9.
+
+\item[\texttt{tcp\_keepalive\_time}] il numero di secondi che devono passare
+ senza traffico sulla connessione prima che il kernel, qualora si sia
+ utilizzata l'opzione \const{SO\_KEEPALIVE} (vedi
+ sez.~\ref{sec:sock_options_main}), inizi ad inviare pacchetti di pacchetti
+ di \textit{keepalive}. Il default è 7200, pari a due ore.
+
+\item[\texttt{tcp\_low\_latency}] un valore logico che indica allo stack TCP
+ del kernel di ottimizzare il comportamento per ottenere tempi di latenza più
+ bassi a scapito di valori più alti per l'utilizzo della banda. Di default è
+ disabilitato in quanto un maggior utilizzo della banda è preferito, ma
+ esistono applicazioni particolari in cui la riduzione della latenza è più
+ importante (ad esempio i cluster di calcolo parallelo) in cui lo si può
+ abilitare.
+
+\item[\texttt{tcp\_max\_orphans}] il numero massimo di socket TCP
+ ``\textsl{orfani}'' (vale a dire non associati a nessun file descriptor)
+ consentito nel sistema.\footnote{trattasi in genere delle connessioni
+ relative a socket chiusi che non hanno completato il processo di
+ chiusura.} Quando il limite viene ecceduto la connessione orfana viene
+ resettata e viene stampato un avvertimento. Questo limite viene usato per
+ contrastare alcuni elementari attacchi di \textit{denial of service}.
+ Diminuire il valore non è mai raccomandato, in certe condizioni di rete può
+ essere opportuno aumentarlo, ma si deve tenere conto del fatto che ciascuna
+ connessione orfana può consumare fino a 64K di memoria del kernel. Il di
+ default viene impostato inizialmente al valore del parametro del kernel
+ \texttt{NR\_FILE}, e viene aggiustato a seconda della memoria disponibile.
+% TODO verificare la spiegazione di connessione orfana
\item[\texttt{tcp\_max\_syn\_backlog}] un numero intero che indica la
lunghezza della coda delle connessioni incomplete, cioè delle connessioni
sia $\mathtt{tcp\_max\_syn\_backlog} \ge \mathtt{16*TCP\_SYNQ\_HSIZE}$,
per poi ricompilare il kernel.}
-\item[\texttt{tcp\_max\_tw\_buckets}]
-\item[\texttt{tcp\_mem}]
-\item[\texttt{tcp\_orphan\_retries}]
-\item[\texttt{tcp\_reordering}]
+\item[\texttt{tcp\_max\_tw\_buckets}] questo valore indica il numero massimo
+ di socket in stato \texttt{TIME\_WAIT} consentito nel sistema; viene
+ impostato per prevenire semplici attacchi di \textit{denial of service} ed
+ inizializzato di default ad un valore del parametro \texttt{NR\_FILE}, per
+ poi essere aggiustato a seconda della memoria presente. Se il valore viene
+ superato il socket viene chiuso con la stampa di un avviso.
+
+
+\item[\texttt{tcp\_mem}] una tripletta di valori usati dallo stack TCP per
+ controllare il proprio uso della memoria. Il primo valore, chiamato
+ \textit{low} nelle pagine di manuale, indica il numero di pagine allocate
+ sotto il quale non viene usato nessun meccanismo di regolazione dell'uso
+ della memoria.
+
+ Il secondo valore, chiamato \textit{pressure} indica il numero di pagine
+ allocate passato il quale lo stack TCP inizia a moderare il suo consumo di
+ memoria. Si esce da questo stato di \textsl{pressione} sulla memoria quando
+ il numero di pagine scende sotto il precedente valore \textit{low}.
+
+ Il terzo valore, chiamato \textit{high} indica il numero massimo di pagine
+ che possono essere utilizzate dallo stack TCP/IP, e soprassiede ogni altro
+ valore specificato dagli altri limiti del kernel.
+
+
+\item[\texttt{tcp\_orphan\_retries}] il numero massimo di volte che si esegue
+ un tentativo di controllo sull'altro capo di una connessione che è stata già
+ chiusa dalla nostra parte. Il valore di default è 8 volte.
+
+\item[\texttt{tcp\_reordering}] il numero massimo di volte che un pacchetto
+ può essere riordinato nel flusso di dati, prima che lo stack TCP assuma che
+ è andato perso e si ponga nello stato di \textit{slow start} (si veda
+ sez.~\ref{sez:tcp_protocol_xxx}) viene usata questa metrica di
+ riconoscimento dei riordinamenti per evitare inutili ritrasmissioni
+ provocate dal riordinamento. Non è opportuno modificare questo valore dal
+ default che è 3.
+
\item[\texttt{tcp\_retrans\_collapse}]
-\item[\texttt{tcp\_retries1}]
+
+\item[\texttt{tcp\_retries1}] imposta il massimo numero di volte che
+ protocollo tenterà la ritrasmissione si un pacchetto su una connessione
+ stabilita prima di fare ricorso ad ulteriori sforzi che coinvolgano anche il
+ livello di rete. Passato questo numero di ritrasmissioni verrà fatto
+ eseguire al livello di rete un tentativo di aggiornamento della rotta verso
+ la destinazione prima di eseguire ogni successiva ritrasmissione.
\item[\texttt{tcp\_retries2}] imposta il numero di tentativi di ritrasmissione
- (il default è 15) di un pacchetto inviato su una connessione già stabilita
- per il quale non si sia ricevuto una risposta di ACK (si veda anche quanto
- illustrato in sez.~\ref{sec:TCP_server_crash}).
+ di un pacchetto inviato su una connessione già stabilita per il quale non si
+ sia ricevuto una risposta di ACK (si veda anche quanto illustrato in
+ sez.~\ref{sec:TCP_server_crash}). Il valore default è 15, che significa un
+ tempo variabile fra 13 e 30 minuti; questo non corrisponde a quanto
+ richiesto nell'\href{http://www.ietf.org/rfc/rfc1122.txt}{RFC~1122} dove è
+ indicato un massimo di 100 secondi, che però è un valore considerato troppo
+ basso.
\item[\texttt{tcp\_rfc1337}]
-\item[\texttt{tcp\_rmem}]
+
+\item[\texttt{tcp\_rmem}]
+
+
\item[\texttt{tcp\_sack}]
\item[\texttt{tcp\_stdurg}]
\item[\texttt{tcp\_synack\_retries}]
\item[\texttt{tcp\_tw\_recycle}]
\item[\texttt{tcp\_tw\_reuse}]
\item[\texttt{tcp\_window\_scaling}]
+
+
\item[\texttt{tcp\_vegas\_cong\_avoid}]
\item[\texttt{tcp\_westwood}]
\item[\texttt{tcp\_wmem}]
% LocalWords: abort overflow adv win app bic convergence dsack ecn fack frto
% LocalWords: intvl probes latency orphans l'ACK SYNQ HSIZE tw buckets mem rfc
% LocalWords: orphan reordering collapse sack stdurg synack syncookies recycle
-% LocalWords: timestamps scaling vegas avoid westwood tcpi l'incapsulazione
+% LocalWords: timestamps scaling vegas avoid westwood tcpi l'incapsulazione NR
% LocalWords: metric EOPNOTSUPP mtu hwaddr ARPHRD interrupt DMA map qlen silly
% LocalWords: rename ifconf syndrome dell'ACK FTP ACCEPTFILTER advanced reno
% LocalWords: congestion control Networking cubic CUBIC highspeed HSTCP htcp
% LocalWords: HTCP hybla HYBLA scalable SCALABLE ifc req iflist access ntoa
+% LocalWords: hop Selective Acknowledgement acknowledgement Explicit RTO stack
+% LocalWords: Notification wireless denial pressure
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
+