connessione annuncia all'altro il massimo ammontare di dati che vorrebbe
accettare per ciascun segmento nella connessione corrente. È possibile
leggere e scrivere questo valore attraverso l'opzione del socket
- \const{TCP\_MAXSEG}.
+ \const{TCP\_MAXSEG} (vedi sez.~\ref{sec:TCP_TCP_opt}).
-\item \textit{window scale
- option}, %come spiegato in sez.~\ref{sec:tcp_protocol}
- il protocollo TCP implementa il controllo di flusso attraverso una
- \textsl{finestra annunciata} (\textit{advertized window}) con la quale
- ciascun capo della comunicazione dichiara quanto spazio disponibile ha in
- memoria per i dati. Questo è un numero a 16 bit dell'header, che così può
- indicare un massimo di 65535 byte;\footnote{ Linux usa come massimo 32767
- per evitare problemi con alcune implementazioni che usano l'aritmetica con
- segno per implementare lo stack TCP.} ma alcuni tipi di connessione come
- quelle ad alta velocità (sopra i 45Mbit/sec) e quelle che hanno grandi
- ritardi nel cammino dei pacchetti (come i satelliti) richiedono una finestra
- più grande per poter ottenere il massimo dalla trasmissione, per questo
- esiste questa opzione che indica un fattore di scala da applicare al valore
- della finestra annunciata\footnote{essendo una nuova opzione per garantire
- la compatibilità con delle vecchie implementazioni del protocollo la
- procedura che la attiva prevede come negoziazione che l'altro capo della
- connessione riconosca esplicitamente l'opzione inserendola anche lui nel
- suo SYN di risposta dell'apertura della connessione.} per la connessione
- corrente (espresso come numero di bit cui spostare a sinistra il valore
- della finestra annunciata inserito nel pacchetto).
+\item \textit{window scale option}, il protocollo TCP implementa il controllo
+ di flusso attraverso una \itindex{advertised~window} \textit{advertised
+ window} (la ``\textsl{finestra annunciata}'', vedi
+ sez.~\ref{sec:tcp_protocol_xxx}) con la quale ciascun capo della
+ comunicazione dichiara quanto spazio disponibile ha in memoria per i dati.
+ Questo è un numero a 16 bit dell'header, che così può indicare un massimo di
+ 65535 byte;\footnote{Linux usa come massimo 32767 per evitare problemi con
+ alcune implementazioni che usano l'aritmetica con segno per implementare
+ lo stack TCP.} ma alcuni tipi di connessione come quelle ad alta velocità
+ (sopra i 45Mbit/sec) e quelle che hanno grandi ritardi nel cammino dei
+ pacchetti (come i satelliti) richiedono una finestra più grande per poter
+ ottenere il massimo dalla trasmissione, per questo esiste questa opzione che
+ indica un fattore di scala da applicare al valore della
+ \itindex{advertised~window} finestra annunciata\footnote{essendo una nuova
+ opzione per garantire la compatibilità con delle vecchie implementazioni
+ del protocollo la procedura che la attiva prevede come negoziazione che
+ l'altro capo della connessione riconosca esplicitamente l'opzione
+ inserendola anche lui nel suo SYN di risposta dell'apertura della
+ connessione.} per la connessione corrente (espresso come numero di bit cui
+ spostare a sinistra il valore della finestra annunciata inserito nel
+ pacchetto).
\item \textit{timestamp option}, è anche questa una nuova opzione necessaria
per le connessioni ad alta velocità per evitare possibili corruzioni di dati
staticamente a \const{IN6ADRR\_LOOPBACK\_INIT}.
-
\subsection{La funzione \func{connect}}
\label{sec:TCP_func_connect}
o problemi nella chiamata della funzione sono le seguenti:
\begin{enumerate}
\item Il client non riceve risposta al SYN: l'errore restituito è
- \errcode{ETIMEDOUT}. Stevens riporta che BSD invia un primo SYN alla chiamata
- di \func{connect}, un altro dopo 6 secondi, un terzo dopo 24 secondi, se
- dopo 75 secondi non ha ricevuto risposta viene ritornato l'errore. Linux
- invece ripete l'emissione del SYN ad intervalli di 30 secondi per un numero
- di volte che può essere stabilito dall'utente sia con una opportuna
- \func{sysctl} che attraverso il filesystem \file{/proc} scrivendo il valore
- voluto in \file{/proc/sys/net/ipv4/tcp\_syn\_retries}. Il valore predefinito
- per la ripetizione dell'invio è di 5 volte, che comporta un timeout dopo
- circa 180 secondi.
+ \errcode{ETIMEDOUT}. Stevens riporta che BSD invia un primo SYN alla
+ chiamata di \func{connect}, un altro dopo 6 secondi, un terzo dopo 24
+ secondi, se dopo 75 secondi non ha ricevuto risposta viene ritornato
+ l'errore. Linux invece ripete l'emissione del SYN ad intervalli di 30
+ secondi per un numero di volte che può essere stabilito dall'utente. Questo
+ può essere fatto a livello globale con una opportuna
+ \func{sysctl},\footnote{o più semplicemente scrivendo il valore voluto in
+ \file{/proc/sys/net/ipv4/tcp\_syn\_retries}, vedi
+ sez.~\ref{sec:sock_ipv4_sysctl}.} e a livello di singolo socket con
+ l'opzione \const{TCP\_SYNCNT} (vedi sez.~\ref{sec:sock_tcp_udp_options}). Il
+ valore predefinito per la ripetizione dell'invio è di 5 volte, che comporta
+ un timeout dopo circa 180 secondi.
\item Il client riceve come risposta al SYN un RST significa che non c'è
nessun programma in ascolto per la connessione sulla porta specificata (il
infatti vengono mantenute due code:
\begin{enumerate}
\item La coda delle connessioni incomplete (\textit{incomplete connection
- queue} che contiene un riferimento per ciascun socket per il quale è
- arrivato un SYN ma il \itindex{three~way~handshake}\textit{three way
+ queue}) che contiene un riferimento per ciascun socket per il quale è
+ arrivato un SYN ma il \itindex{three~way~handshake} \textit{three way
handshake} non si è ancora concluso. Questi socket sono tutti nello stato
\texttt{SYN\_RECV}.
-\item La coda delle connessioni complete (\textit{complete connection queue}
+\item La coda delle connessioni complete (\textit{complete connection queue})
che contiene un ingresso per ciascun socket per il quale il
\itindex{three~way~handshake} \textit{three way handshake} è stato
completato ma ancora \func{accept} non è ritornata. Questi socket sono
sempre attivo il campo \texttt{ack}, seguito dal numero di sequenza per il
quale si da il ricevuto; quest'ultimo, a partire dal terzo pacchetto, viene
espresso in forma relativa per maggiore compattezza. Il campo \texttt{win} in
-ogni riga indica la \textit{advertising window} di cui parlavamo in
-sez.~\ref{sec:TCP_TCP_opt}. Allora si può verificare dall'output del comando
-come venga appunto realizzata la sequenza di pacchetti descritta in
-sez.~\ref{sec:TCP_conn_cre}: prima viene inviato dal client un primo pacchetto
-con il SYN che inizia la connessione, a cui il server risponde dando il
-ricevuto con un secondo pacchetto, che a sua volta porta un SYN, cui il client
-risponde con un il terzo pacchetto di ricevuto.
+ogni riga indica la \itindex{advertised~window} \textit{advertised window} di
+cui parlavamo in sez.~\ref{sec:TCP_TCP_opt}. Allora si può verificare
+dall'output del comando come venga appunto realizzata la sequenza di pacchetti
+descritta in sez.~\ref{sec:TCP_conn_cre}: prima viene inviato dal client un
+primo pacchetto con il SYN che inizia la connessione, a cui il server risponde
+dando il ricevuto con un secondo pacchetto, che a sua volta porta un SYN, cui
+il client risponde con un il terzo pacchetto di ricevuto.
Ritorniamo allora alla nostra sessione con il servizio echo: dopo le tre righe
del \textit{three way handshake} \itindex{three~way~handshake} non avremo nulla
caso di Linux anche dall'impostazione di alcuni dei parametri di sistema che
si trovano in \file{/proc/sys/net/ipv4}, che ne controllano il comportamento:
in questo caso in particolare da \file{tcp\_retries2} (vedi
-sez.~\ref{sec:sock_sysctl}). Questo parametro infatti specifica il numero di
-volte che deve essere ritentata la ritrasmissione di un pacchetto nel mezzo di
-una connessione prima di riportare un errore di timeout. Il valore
+sez.~\ref{sec:sock_ipv4_sysctl}). Questo parametro infatti specifica il numero
+di volte che deve essere ritentata la ritrasmissione di un pacchetto nel mezzo
+di una connessione prima di riportare un errore di timeout. Il valore
preimpostato è pari a 15, il che comporterebbe 15 tentativi di ritrasmissione,
ma nel nostro caso le cose sono andate diversamente, dato che le
ritrasmissioni registrate da \cmd{tcpdump} sono solo 8; inoltre l'errore
possono utilizzare questi valori per far si che \func{select} ritorni solo
quando c'è la certezza di avere dati a sufficienza.\footnote{questo tipo di
controllo è utile di norma solo per la lettura, in quanto in genere le
- operazioni di scrittura sono già controllate dall'applicazione, che sà
+ operazioni di scrittura sono già controllate dall'applicazione, che sa
sempre quanti dati invia, mentre non è detto possa conoscere la quantità di
dati in ricezione; per cui, nella situazione in cui si conosce almeno un
valore minimo, per evitare la penalizzazione dovuta alla ripetizione delle
disponibilità.
Il nostro server comunque soffre di una vulnerabilità per un attacco di tipo
-\textit{Denial of Service}. Il problema è che in caso di blocco di una
-qualunque delle funzioni di I/O, non avendo usato processi separati, tutto il
-server si ferma e non risponde più a nessuna richiesta. Abbiamo scongiurato
-questa evenienza per l'I/O in ingresso con l'uso di \func{select}, ma non vale
-altrettanto per l'I/O in uscita. Il problema pertanto può sorgere qualora una
-delle chiamate a \func{write} effettuate da \func{FullWrite} si blocchi. Con
-il funzionamento normale questo non accade in quanto il server si limita a
-scrivere quanto riceve in ingresso, ma qualora venga utilizzato un client
-malevolo che esegua solo scritture e non legga mai indietro l'\textsl{eco} del
-server, si potrebbe giungere alla saturazione del buffer di scrittura, ed al
-conseguente blocco del server su di una \func{write}.
+\itindex{Denial~of~Service~(DoS)} \textit{Denial of Service}. Il problema è
+che in caso di blocco di una qualunque delle funzioni di I/O, non avendo usato
+processi separati, tutto il server si ferma e non risponde più a nessuna
+richiesta. Abbiamo scongiurato questa evenienza per l'I/O in ingresso con
+l'uso di \func{select}, ma non vale altrettanto per l'I/O in uscita. Il
+problema pertanto può sorgere qualora una delle chiamate a \func{write}
+effettuate da \func{FullWrite} si blocchi. Con il funzionamento normale questo
+non accade in quanto il server si limita a scrivere quanto riceve in ingresso,
+ma qualora venga utilizzato un client malevolo che esegua solo scritture e non
+legga mai indietro l'\textsl{eco} del server, si potrebbe giungere alla
+saturazione del buffer di scrittura, ed al conseguente blocco del server su di
+una \func{write}.
Le possibili soluzioni in questo caso sono quelle di ritornare ad eseguire il
ciclo di risposta alle richieste all'interno di processi separati, utilizzare
% LocalWords: SNDLOWAT third fset maxfd fileno ISSET closed how SHUT RD WR eof
% LocalWords: RDWR fifo Trip ping fourth CLR sull'I SETSIZE nread break Denial
% LocalWords: Service poll POLLIN POLLRDNORM POLLPRI POLLRDBAND POLLOUT events
-% LocalWords: POLLHUP POLLERR revents pollfd
+% LocalWords: POLLHUP POLLERR revents pollfd Di
%%% Local Variables:
%%% mode: latex