%% 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
\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 Discovery.\\
+ imposta il Path MTU \itindex{Maximum~Transfer~Unit} Discovery.\\
\const{IP\_MTU} &$\bullet$& & &\texttt{int}&
- legge il valore attuale della MTU.\\
+ legge il valore attuale della \itindex{Maximum~Transfer~Unit} MTU.\\
\const{IP\_ROUTER\_ALERT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
imposta l'opzione \textit{IP router alert} sui pacchetti.\\
\const{IP\_MULTICAST\_TTL} &$\bullet$&$\bullet$& &\texttt{int}&
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}), l'indirizzo locale da esso
+ 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}).
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.
+ \itindex{Maximum~Transfer~Unit} \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{Maximum~Transfer~Unit}
Il protocollo che supporta il maggior numero di opzioni è TCP; per poterle
utilizzare occorre specificare \const{SOL\_TCP} (o l'equivalente
\const{IPPROTO\_TCP}) come valore per l'argomento \param{level}. Si sono
-riportate le varie opzioni disponibili in tab.~\ref{tab:sock_opt_tcp}, dove
-sono elencate le rispettive costanti da utilizzare come valore per l'argomento
-\param{optname}. Dette costanti e tutte le altre costanti e strutture
-collegate all'uso delle opzioni TCP sono definite in \file{netinet/tcp.h}, ed
-accessibili includendo detto file.\footnote{in realtà questo è il file usato
- dalle librerie; la definizione delle opzioni effettivamente supportate da
- Linux si trova nel file \texttt{linux/tcp.h}, dal quale si sono estratte le
- costanti di tab.~\ref{tab:sock_opt_tcplevel}.}
+riportate le varie opzioni disponibili in tab.~\ref{tab:sock_opt_tcplevel},
+dove sono elencate le rispettive costanti da utilizzare come valore per
+l'argomento \param{optname}. Dette costanti e tutte le altre costanti e
+strutture collegate all'uso delle opzioni TCP sono definite in
+\file{netinet/tcp.h}, ed accessibili includendo detto file.\footnote{in realtà
+ questo è il file usato dalle librerie; la definizione delle opzioni
+ effettivamente supportate da Linux si trova nel file \texttt{linux/tcp.h},
+ dal quale si sono estratte le costanti di tab.~\ref{tab:sock_opt_tcplevel}.}
\begin{table}[!htb]
\centering
restituisce informazioni sul socket.\\
\const{TCP\_QUICKACK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}&
abilita la modalità \textit{quickack}.\\
- \const{TCP\_CONGESTION} &$\bullet$&$\bullet$&? &\texttt{?}& %???
- non ancora documentata.\\
+ \const{TCP\_CONGESTION} &$\bullet$&$\bullet$& &\texttt{char *}&
+ imposta l'algoritmo per il controllo della congestione.\\
\hline
\end{tabular}
\caption{Le opzioni per i socket TCP disponibili al livello
tab.~\ref{tab:sock_opt_tcplevel} sono estremamente sintetiche ed indicative,
la spiegazione del funzionamento delle singole opzioni con una maggiore
quantità di dettagli è fornita nel seguente elenco:
-\begin{basedescript}{\desclabelwidth{3.3cm}\desclabelstyle{\nextlinelabel}}
+\begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}}
+
\item[\const{TCP\_NODELAY}] il protocollo TCP utilizza un meccanismo di
bufferizzazione dei dati uscenti, per evitare la trasmissione di tanti
trasmessi; per evitare situazioni del genere è stato introdotto
l'\textsl{algoritmo di Nagle}.} Questo meccanismo è controllato da un
apposito algoritmo (detto \textsl{algoritmo di Nagle}, vedi
- sez.\ref{sez:tcp_protocol_xxx}). Il comportamento normale del protocollo
+ sez.~\ref{sez:tcp_protocol_xxx}). Il comportamento normale del protocollo
prevede che i dati siano accumulati fintanto che non si raggiunge una
quantità considerata adeguata per eseguire la trasmissione di un singolo
segmento.
kernel 2.5.71.}
\item[\const{TCP\_MAXSEG}] con questa opzione si legge o si imposta il valore
- della \itindex{Maximum~Segment~Size} MSS (vedi sez.~\ref{sec:net_lim_dim} e
- sez.\ref{sez:tcp_protocol_xxx}) dei segmenti TCP uscenti. Se l'opzione è
- impostata prima di stabilire la connessione, si cambia anche il valore della
- \itindex{Maximum~Segment~Size} MSS annunciata all'altro capo della
- connessione. Se si specificano valori maggiori della MTU questi verranno
- ignorati, inoltre TCP imporrà anche i suoi limiti massimo e minimo per
- questo valore.
+ della \itindex{Maximum~Segment~Size} MSS (\textit{Maximum~Segment~Size},
+ vedi sez.~\ref{sec:net_lim_dim} e sez.~\ref{sez:tcp_protocol_xxx}) dei
+ segmenti TCP uscenti. Se l'opzione è impostata prima di stabilire la
+ connessione, si cambia anche il valore della \itindex{Maximum~Segment~Size}
+ MSS annunciata all'altro capo della connessione. Se si specificano valori
+ maggiori della \itindex{Maximum~Transfer~Unit} MTU questi verranno ignorati,
+ inoltre TCP imporrà anche i suoi limiti massimo e minimo per questo valore.
\item[\const{TCP\_CORK}] questa opzione è il complemento naturale di
\const{TCP\_NODELAY} e serve a gestire a livello applicativo la situazione
Si usa molto spesso \const{TCP\_CORK} quando si effettua il trasferimento
diretto di un blocco di dati da un file ad un socket con \func{sendfile}
- (vedi sez.~\ref{sec:file_sendfile}), per inserire una intestazione prima
- della chiamata a questa funzione; senza di essa l'intestazione potrebbe
- venire spedita in un segmento a parte, che a seconda delle condizioni
- potrebbe richiedere anche una risposta di ACK, portando ad una notevole
- penalizzazione delle prestazioni.
+ (vedi sez.~\ref{sec:file_sendfile_splice}), per inserire una intestazione
+ prima della chiamata a questa funzione; senza di essa l'intestazione
+ potrebbe venire spedita in un segmento a parte, che a seconda delle
+ condizioni potrebbe richiedere anche una risposta di ACK, portando ad una
+ notevole penalizzazione delle prestazioni.
Si tenga presente che l'implementazione corrente di \const{TCP\_CORK} non
consente di bloccare l'invio dei dati per più di 200 millisecondi, passati i
dopo l'emissione dell'ultimo segmento di ACK.
Di nuovo esistono situazioni (e la più tipica è quella di una richiesta
- HTTP) in cui sarebbe utilie inviare immediatamente la richiesta all'interno
+ HTTP) in cui sarebbe utile inviare immediatamente la richiesta all'interno
del segmento con l'ultimo ACK del \itindex{three~way~handshake}
\textit{three way handshake}; si potrebbe così risparmiare l'invio di un
segmento successivo per la richiesta e il ritardo sul server fra la
Allo stesso tempo il protocollo TCP prevede che sul lato del server la
funzione \func{accept} ritorni dopo la ricezione dell'ACK finale, in tal
- caso quello che si fà usualmente è lanciare un nuovo processo per leggere i
- successivi dati che si bloccherà su una \func{read} se questi non sono
- disponibili, ma così si saranno impiegate delle risorse (per la creazione
- del nuovo processo) che non saranno usate immediatamente. L'uso di
- \const{TCP\_DEFER\_ACCEPT} consente di intervenire anche in questa
+ caso quello che si fa usualmente è lanciare un nuovo processo per leggere i
+ successivi dati, che si bloccherà su una \func{read} se questi non sono
+ disponibili; in questo modo si saranno impiegate delle risorse (per la
+ creazione del nuovo processo) che non vengono usate immediatamente. L'uso
+ di \const{TCP\_DEFER\_ACCEPT} consente di intervenire anche in questa
situazione; quando la si invoca sul lato server (vale a dire su un socket in
ascolto) l'opzione fa sì che \func{accept} ritorni soltanto quando sono
presenti dei dati sul socket, e non alla ricezione dell'ACK conclusivo del
\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{sez:tcp_protocol_xxx}). Il kernel impone comunque una dimensione
+ sez.~\ref{sez: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.
-\item[\const{TCP\_INFO}] questa opzione, specifica di Linux, ma introdotta
- anche in altri kernel (ad esempio FreeBSD) permette di controllare lo stato
- di un socket TCP in user space. L'opzione restituisce in una speciale
- struttura \struct{tcp\_info}, la cui definizione è riportata in
- fig.~\ref{fig:tcp_info_struct}, tutta una serie di dati relativi al socket.
- Anche questa opzione deve essere evitata se si vuole scrivere codice
- portabile.
-
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
\label{fig:tcp_info_struct}
\end{figure}
-Con questa opzione diventa possibile ricevere una serie di informazioni
-relative ad un socket TCP così da poter effettuare dei controlli senza dover
-passare attraverso delle operazioni di lettura. Ad esempio si può verificare
-se un socket è stato chiuso usando una funzione analoga a quella illustrata in
-fig.~\ref{fig:is_closing}, in cui si utilizza il valore del campo
-\var{tcpi\_state} di \struct{tcp\_info} per controllare lo stato del socket.
+\item[\const{TCP\_INFO}] questa opzione, specifica di Linux, ma introdotta
+ anche in altri kernel (ad esempio FreeBSD) permette di controllare lo stato
+ interno di un socket TCP direttamente da un programma in user space.
+ L'opzione restituisce in una speciale struttura \struct{tcp\_info}, la cui
+ definizione è riportata in fig.~\ref{fig:tcp_info_struct}, tutta una serie
+ di dati che il kernel mantiene, relativi al socket. Anche questa opzione
+ deve essere evitata se si vuole scrivere codice portabile.
+
+ Con questa opzione diventa possibile ricevere una serie di informazioni
+ relative ad un socket TCP così da poter effettuare dei controlli senza dover
+ passare attraverso delle operazioni di lettura. Ad esempio si può verificare
+ se un socket è stato chiuso usando una funzione analoga a quella illustrata
+ in fig.~\ref{fig:is_closing}, in cui si utilizza il valore del campo
+ \var{tcpi\_state} di \struct{tcp\_info} per controllare lo stato del socket.
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \includestruct{listati/tcp_info.h}
+ \includecodesnip{listati/is_closing.c}
\end{minipage}
\caption{Codice della funzione \texttt{is\_closing.c}, che controlla lo stato
di un socket TCP per verificare se si sta chiudendo.}
\label{fig:is_closing}
\end{figure}
+%Si noti come nell'esempio si sia (
+
+
\item[\const{TCP\_QUICKACK}] con questa opzione è possibile eseguire una forma
di controllo sull'invio dei segmenti ACK all'interno di in flusso di dati su
TCP. In genere questo invio viene gestito direttamente dal kernel, il
% TODO trattare con gli esempi di apache
-\item[\const{TCP\_CONGESTION}] questa opzione permette di controllare gli
- algoritmi usati dal protocollo TCP per la gestione della connessione. É
- stata introdotta con il kernel 2.6.13, e non è documentata.
+\item[\const{TCP\_CONGESTION}] questa opzione permette di impostare quale
+ algoritmo per il controllo della congestione\footnote{il controllo della
+ congestione è un meccanismo previsto dal protocollo TCP (vedi
+ sez.~\ref{sez:tcp_protocol_xxx}) per evitare di trasmettere inutilmente
+ dati quando una connessione è congestionata; un buon algoritmo è
+ fondamentale per il funzionamento del protocollo, dato che i pacchetti
+ persi andrebbero ritrasmessi, per cui inviare un pacchetto su una linea
+ congestionata potrebbe causare facilmente un peggioramento della
+ situazione.} utilizzare per il singolo socket. L'opzione è stata
+ introdotta con il kernel 2.6.13,\footnote{alla data di stesura di queste
+ note (Set. 2006) è pure scarsamente documentata, tanto che non è neanche
+ definita nelle intestazioni delle \acr{glibc} per cui occorre definirla a
+ mano al suo valore che è 13.} e prende come per \param{optval} il
+ puntatore ad un buffer contenente il nome dell'algoritmo di controllo che
+ si vuole usare.
+
+ L'uso di un nome anziché di un valore numerico è dovuto al fatto che gli
+ algoritmi di controllo della congestione sono realizzati attraverso
+ altrettanti moduli del kernel, e possono pertanto essere attivati a
+ richiesta; il nome consente di caricare il rispettivo modulo e di introdurre
+ moduli aggiuntivi che implementino altri meccanismi.
+
+ Per poter disporre di questa funzionalità occorre aver compilato il kernel
+ attivando l'opzione di configurazione generale
+ \texttt{TCP\_CONG\_ADVANCED},\footnote{disponibile come \textit{TCP:
+ advanced congestion control} nel menù \textit{Network->Networking
+ options}, che a sua volta renderà disponibile un ulteriore menù con gli
+ algoritmi presenti.} e poi abilitare i singoli moduli voluti con le varie
+ \texttt{TCP\_CONG\_*} presenti per i vari algoritmi disponibili; un elenco
+ di quelli attualmente supportati nella versione ufficiale del kernel è
+ riportato in tab.~\ref{tab:sock_tcp_congestion_algo}.\footnote{la lista è
+ presa dalla versione 2.6.17.}
+
+
+ Si tenga presente che prima della implementazione modulare alcuni di questi
+ algoritmi erano disponibili soltanto come caratteristiche generali del
+ sistema, attivabili per tutti i socket, questo è ancora possibile con la
+ \textit{sysctl} \texttt{tcp\_congestion\_control} (vedi
+ sez.~\ref{sec:sock_ipv4_sysctl}) che ha sostituito le precedenti
+ \textit{sysctl}.\footnote{riportate anche, alla data di stesura di queste
+ pagine (Set. 2006) nelle pagine di manuale, ma non più presenti.}
+
+ \begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|p{10cm}|}
+ \hline
+ \textbf{Nome}&\textbf{Configurazione}&\textbf{Riferimento} \\
+ \hline
+ \hline
+ reno& -- &algoritmo tradizionale, usato in caso di assenza degli altri.\\
+ \texttt{bic} &\texttt{TCP\_CONG\_BIC} &
+ \href{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}
+ {\texttt{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}}.\\
+ \texttt{cubic} &\texttt{TCP\_CONG\_CUBIC} &
+ \href{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}
+ {\texttt{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}}.\\
+ \texttt{highspeed}&\texttt{TCP\_CONG\_HSTCP} &
+ \href{http://www.icir.org/floyd/hstcp.html}
+ {\texttt{http://www.icir.org/floyd/hstcp.html}}.\\
+ \texttt{htcp} &\texttt{TCP\_CONG\_HTCP} &
+ \href{http://www.hamilton.ie/net/htcp/}
+ {\texttt{http://www.hamilton.ie/net/htcp/}}.\\
+ \texttt{hybla} &\texttt{TCP\_CONG\_HYBLA} &
+ \href{http://www.danielinux.net/projects.html}
+ {\texttt{http://www.danielinux.net/projects.html}}.\\
+ \texttt{scalable}&\texttt{TCP\_CONG\_SCALABLE}&
+ \href{http://www.deneholme.net/tom/scalable/}
+ {\texttt{http://www.deneholme.net/tom/scalable/}}.\\
+ \texttt{vegas} &\texttt{TCP\_CONG\_VEGAS} &
+ \href{http://www.cs.arizona.edu/protocols/}
+ {\texttt{http://www.cs.arizona.edu/protocols/}}.\\
+ \texttt{westwood}&\texttt{TCP\_CONG\_WESTWOOD}&
+ \href{http://www.cs.ucla.edu/NRL/hpi/tcpw/}
+ {\texttt{http://www.cs.ucla.edu/NRL/hpi/tcpw/}}.\\
+% \texttt{}&\texttt{}& .\\
+ \hline
+ \end{tabular}
+ \caption{Gli algoritmi per il controllo della congestione disponibili con
+ Linux con le relative opzioni di configurazione da attivare.}
+ \label{tab:sock_tcp_congestion_algo}
+ \end{table}
\end{basedescript}
Il protocollo UDP, anche per la sua maggiore semplicità, supporta un numero
-ridotto di opzioni, riportate in tab.~\ref{tab:sock_opt_udp}; anche in questo
-caso per poterle utilizzare occorrerà impostare l'opportuno valore per
+ridotto di opzioni, riportate in tab.~\ref{tab:sock_opt_udplevel}; anche in
+questo caso per poterle utilizzare occorrerà impostare l'opportuno valore per
l'argomento \param{level}, che è \const{SOL\_UDP} (o l'equivalente
\const{IPPROTO\_UDP}). Le costanti che identificano dette opzioni sono
definite in \file{netinet/udp.h}, ed accessibili includendo detto
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
- all'interno dei comandi; si può ottenere un elenco delle interfacce che
- contiene anche il valore del relativo indice usando il comando \cmd{ip
- link}.
+ all'interno dei comandi. Una modalità per ottenere questo valore è usare il
+ comando \cmd{ip link}, che fornisce un elenco delle interfacce presenti
+ ordinato in base a tale valore (riportato come primo campo).
+
\item[\const{SIOCGIFINDEX}] restituisce nel campo \var{ifr\_ifindex} il valore
numerico dell'indice dell'interfaccia specificata con \var{ifr\_name}, è in
\item[\const{SIOCGIFMETRIC}] permette di leggere il valore della metrica del
dispositivo associato all'interfaccia specificata nel campo
- \var{ifr\_metric}, attualmente non ancora implementato, restituisce sempre 0
- come valore.
+ \var{ifr\_metric}. Attualmente non è implementato, e l'operazione
+ restituisce sempre un valore nullo.
\item[\const{SIOCSIFMETRIC}] permette di impostare il valore della metrica del
dispositivo al valore specificato nel campo \var{ifr\_metric}, attualmente
\end{basedescript}
-Una ulteriore operazione che consente di ricavare le caratteristiche delle
-interfacce di rete, che però è disponibile soltanto per socket della famiglia
-\const{AF\_INET} (vale ad dire per socket IPv4), è \const{SIOCGIFCONF}. In
-questo caso l'utente dovrà passare come argomento una struttura
-\struct{ifconf}, definita in fig.~\ref{fig:netdevice_ifconf_struct}.
+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
+\const{AF\_INET} (vale ad dire per socket IPv4). In questo caso l'utente dovrà
+passare come argomento una struttura \struct{ifconf}, definita in
+fig.~\ref{fig:netdevice_ifconf_struct}.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:netdevice_ifconf_struct}
\end{figure}
+Per eseguire questa operazione occorrerà allocare preventivamente un buffer di
+contenente un vettore di strutture \struct{ifreq}. La dimensione (in byte) di
+questo buffer deve essere specificata nel campo \var{ifc\_len} di
+\struct{ifconf}, mentre il suo indirizzo andrà specificato nel campo
+\var{ifc\_req}. Qualora il buffer sia stato allocato come una stringa, il suo
+indirizzo potrà essere fornito usando il campo \var{ifc\_buf}.\footnote{si
+ noti che l'indirizzo del buffer è definito in \struct{ifconf} con una
+ \ctyp{union}, questo consente di utilizzare una delle due forme a piacere.}
+
+La funzione restituisce nel buffer indicato una serie di strutture
+\struct{ifreq} contenenti nel campo \var{ifr\_name} il nome dell'interfaccia e
+nel campo \var{ifr\_addr} il relativo indirizzo IP. Se lo spazio allocato nel
+buffer è sufficiente il kernel scriverà una struttura \struct{ifreq} per
+ciascuna interfaccia attiva, restituendo nel campo \var{ifc\_len} il totale
+dei byte effettivamente scritti. Il valore di ritorno è 0 se l'operazione ha
+avuto successo e negativo in caso contrario.
+
+Si tenga presente che il kernel non scriverà mai sul buffer di uscita dati
+eccedenti numero di byte specificato col valore di \var{ifc\_len} impostato
+alla chiamata della funzione, troncando il risultato se questi non dovessero
+essere sufficienti. Questa condizione non viene segnalata come errore per cui
+occorre controllare il valore di \var{ifc\_len} all'uscita della funzione, e
+verificare che esso sia inferiore a quello di ingresso. In caso contrario si è
+probabilmente\footnote{probabilmente perché si potrebbe essere nella
+ condizione in cui sono stati usati esattamente quel numero di byte.} avuta
+una situazione di troncamento dei dati.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includecodesample{listati/iflist.c}
+ \end{minipage}
+ \caption{Il corpo principale del programma \texttt{iflist.c}.}
+ \label{fig:netdevice_iflist}
+\end{figure}
+
+Come esempio dell'uso di queste funzioni si è riportato in
+fig.~\ref{fig:netdevice_iflist} il corpo principale del programma
+\texttt{iflist} in cui si utilizza l'operazione \const{SIOCGIFCONF} per
+ottenere una lista delle interfacce attive e dei relativi indirizzi. Al solito
+il codice completo è fornito nei sorgenti allegati alla guida.
+
+Il programma inizia (\texttt{\small 7--11}) con la creazione del socket
+necessario ad eseguire l'operazione, dopo di che si inizializzano
+opportunamente (\texttt{\small 13--14}) i valori della struttura
+\struct{ifconf} indicando la dimensione del buffer ed il suo
+indirizzo;\footnote{si noti come in questo caso si sia specificato l'indirizzo
+ usando il campo \var{ifc\_buf}, mentre nel seguito del programma si accederà
+ ai valori contenuti nel buffer usando \var{ifc\_req}.} si esegue poi
+l'operazione invocando \func{ioctl}, controllando come sempre la corretta
+esecuzione, ed uscendo in caso di errore (\texttt{\small 15--19}).
+
+Si esegue poi un controllo sulla quantità di dati restituiti segnalando un
+eventuale overflow del buffer (\texttt{\small 21--23}); se invece è tutto a
+posto (\texttt{\small 24--27}) si calcola e si stampa a video il numero di
+interfacce attive trovate. L'ultima parte del programma (\texttt{\small
+ 28--33}) è il ciclo sul contenuto delle varie strutture \struct{ifreq}
+restituite in cui si estrae (\texttt{\small 30}) l'indirizzo ad esse
+assegnato\footnote{si è definito \var{access} come puntatore ad una struttura
+ di tipo \struct{sockaddr\_in} per poter eseguire un \textit{casting}
+ dell'indirizzo del valore restituito nei vari campi \var{ifr\_addr}, così
+ poi da poterlo poi usare come argomento di \func{inet\_ntoa}.} e lo si
+stampa (\texttt{\small 31--32}) insieme al nome 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
conflitti con le porte usate dai servizi noti.
\item[\texttt{ip\_no\_pmtu\_disc}] imposta la disciplina di ricerca della
- \textit{Path MTU} (vedi sez.~\ref{sec:net_lim_dim} e
- sez.~\ref{sec:sock_ipv4_options}).
+ \itindex{Maximum~Transfer~Unit} \textit{Path MTU} (vedi
+ sez.~\ref{sec:net_lim_dim} e sez.~\ref{sec:sock_ipv4_options}).
\item[\texttt{ipfrag\_high\_thresh}] limite massimo (espresso in numero di
byte) sui pacchetti IP frammentati presenti in coda; quando questo valore
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}]
\end{basedescript}
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "gapil"
-%%% End:
-
-
-
% LocalWords: socket sez dotted decimal resolver Domain Name Service cap DNS
% LocalWords: client fig LDAP Lightweight Access Protocol NIS Information Sun
% LocalWords: like netgroup Switch Solaris glibc libc uclib NSS tab shadow uid
% 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: metric EOPNOTSUPP mtu hwaddr ARPHRD interrupt DMA map qlen
-% LocalWords: rename ifconf
+% 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:
+