X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=sockctrl.tex;h=f90a45eb5cff9fff18e7f2aef8e1f99e7816b5b9;hb=1df343113e14ea885c3c3fdb985b2cb84230bd62;hp=18cada6e51c6bb9b0a4e9faffa384ac59eba370c;hpb=e35bdc25982790962f06f395b8329634d67448e9;p=gapil.git diff --git a/sockctrl.tex b/sockctrl.tex index 18cada6..f90a45e 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -2239,9 +2239,10 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni: \item[\const{SO\_SNDBUF}] questa opzione imposta la dimensione del buffer di uscita del socket. Prende per \param{optval} un intero indicante il numero - di byte. Il valore di default ed il valore massimo che si può specificare - come argomento per questa opzione sono impostabili tramiti gli opportuni - valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}). + di byte. Il valore di default ed il valore massimo che si possono + specificare come argomento per questa opzione sono impostabili + rispettivamente tramite gli opportuni valori di \func{sysctl} (vedi + sez.~\ref{sec:sock_sysctl}). \item[\const{SO\_RCVBUF}] questa opzione imposta la dimensione del buffer di ingresso del socket. Prende per \param{optval} un intero indicante il numero @@ -2249,6 +2250,23 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni: come argomento per questa opzione sono impostabili tramiti gli opportuni valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}). + Si tenga presente che nel caso di socket TCP, per entrambe le opzioni + \const{SO\_RCVBUF} e \const{SO\_SNDBUF}, il kernel alloca effettivamente una + quantità di memoria doppia rispetto a quanto richiesto con + \func{setsockopt}. Questo comporta che una successiva lettura con + \func{getsockopt} riporterà un valore diverso da quello impostato con + \func{setsockopt}. Questo avviene perché TCP necessita dello spazio in più + per mantenere dati amministrativi e strutture interne, e solo una parte + viene usata come buffer per i dati, mentre il valore letto da + \func{getsockopt} e quello riportato nei vari parametri di + \textit{sysctl}\footnote{cioè \texttt{wmem\_max} e \texttt{rmem\_max} in + \texttt{/proc/sys/net/core} e \texttt{tcp\_wmem} e \texttt{tcp\_rmem} in + \texttt{/proc/sys/net/ipv4}, vedi sez.~\ref{sec:sock_sysctl}.} indica la + memoria effettivamente impiegata. Si tenga presente inoltre che le + modifiche alle dimensioni dei buffer di ingresso e di uscita per poter + essere effettive devono essere impostate prima della chiamata alle funzioni + \func{listen} o \func{connect}. + \item[\const{SO\_LINGER}] questa opzione controlla le modalità con cui viene chiuso un socket quando si utilizza un protocollo che supporta le connessioni (è pertanto usata con i socket TCP ed ignorata per UDP) e @@ -2298,52 +2316,53 @@ approfondimento sul significato delle opzioni generiche pi La prima opzione da approfondire è \const{SO\_KEEPALIVE} che permette di tenere sotto controllo lo stato di una connessione. Una connessione infatti -resta attiva anche quando non viene effettuato alcun traffico su di essa, -questo può comportare che un crollo della connessione, qualora avvenisse ad -esempio in conseguenza di una interruzione completa della rete, potrebbe -passare inosservato. +resta attiva anche quando non viene effettuato alcun traffico su di essa; è +allora possibile, in caso di una interruzione completa della rete, che la +caduta della connessione non venga rilevata, dato che sulla stessa non passa +comunque alcun traffico. Se si imposta questa opzione, è invece cura del kernel inviare degli appositi messaggi sulla rete, detti appunto \textit{keep-alive}, per verificare se la -connessione è attiva. L'opzione funziona soltanto con socket che supportino +connessione è attiva. L'opzione funziona soltanto con i socket che supportano le connessioni (non ha senso per socket UDP ad esempio) e si applica principalmente ai socket TCP. Con le impostazioni di default (che sono riprese da BSD) Linux emette un messaggio di \textit{keep-alive}\footnote{in sostanza un segmento ACK vuoto, cui sarà risposto con un altro segmento ACK vuoto.} verso l'altro capo della -connessione se questa è rimasta senza traffico per più di due ore. Se è tutto +connessione se questa è rimasta senza traffico per più di due ore. Se è tutto a posto il messaggio viene ricevuto e verrà emesso un segmento ACK di risposta, alla cui ricezione ripartirà un altro ciclo di attesa per altre due ore di inattività; il tutto avviene all'interno del kernel e le applicazioni non riceveranno nessun dato. -In caso di problemi invece si possono avere i due casi già illustrati in -sez.~\ref{sec:TCP_conn_crash} per il caso di terminazione precoce del server: -il primo è quello in cui la macchina remota è caduta ed è stata riavviata, per -cui dopo il riavvio la connessione non viene più riconosciuta,\footnote{si - ricordi che un normale riavvio non ha questo effetto, in quanto in tal caso - si passa per la chiusura del processo, e questo, come illustrato in - sez.~\ref{sec:file_close}, comporta la chiusura del socket con l'invio di un - segmento FIN all'altro capo della connessione, che verrà regolarmente - chiusa.} in questo caso all'invio del messaggio di \textit{keep-alive} si -otterrà come risposta un segmento RST che indica che l'altro capo non -riconosce più l'esistenza della connessione. In tal caso il socket viene -chiuso dopo aver impostato un errore \errcode{ECONNRESET}. +Qualora ci siano dei problemi di rete si possono invece verificare i due casi +di terminazione precoce del server già illustrati in +sez.~\ref{sec:TCP_conn_crash}. Il primo è quello in cui la macchina remota ha +avuto un crollo del sistema ed è stata riavviata, per cui dopo il riavvio la +connessione non esiste più.\footnote{si ricordi che un normale riavvio o il + crollo dell'applicazione non ha questo effetto, in quanto in tal caso si + passa sempre per la chiusura del processo, e questo, come illustrato in + sez.~\ref{sec:file_close}, comporta anche la regolare chiusura del socket + con l'invio di un segmento FIN all'altro capo della connessione.} In questo +caso all'invio del messaggio di \textit{keep-alive} si otterrà come risposta +un segmento RST che indica che l'altro capo non riconosce più l'esistenza +della connessione ed il socket verrà chiuso riportanto un errore di +\errcode{ECONNRESET}. Se invece non viene ricevuta nessuna risposta (indice che la macchina non è più raggiungibile) l'emissione dei messaggi viene ripetuta ad intervalli di 75 secondi per un massimo di 9 volte\footnote{entrambi questi valori possono - essere opportunamente modificati con gli opportuni parametri illustrati in - sez.~\ref{sec:sock_sysctl}, si tenga presente che però questo vale a livello - di kernel ed i suddetti valori saranno applicati a \textsl{tutti} i socket.} -(per un totale di 11 minuti e 15 secondi) dopo di che, se non si è ricevuta -nessuna risposta, il socket viene chiuso dopo aver impostato un errore di -\errcode{ETIMEDOUT}. Qualora la connessione si sia ristabilita e si riceva un -successivo messaggio di risposta il ciclo riparte come se niente fosse -avvenuto. Infine se invece si riceve come risposta un pacchetto ICMP di -destinazione irraggiungibile (vedi sez.~\ref{sec:icmp_protocol_xxx}), verrà -restituito l'errore corrispondente. + essere opportunamente modificati a livello di sistema (cioè per tutti i + socket) con gli opportuni parametri illustrati in sez.~\ref{sec:sock_sysctl} + ed a livello di singolo socket con le opzioni \texttt{TCP\_KEEP*} di + sez.~\ref{sec:sock_tcp_udp_options}.} (per un totale di 11 minuti e 15 +secondi) dopo di che, se non si è ricevuta nessuna risposta, il socket viene +chiuso dopo aver impostato un errore di \errcode{ETIMEDOUT}. Qualora la +connessione si sia ristabilita e si riceva un successivo messaggio di risposta +il ciclo riparte come se niente fosse avvenuto. Infine se invece si riceve +come risposta un pacchetto ICMP di destinazione irraggiungibile (vedi +sez.~\ref{sec:icmp_protocol_xxx}), 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 @@ -2351,9 +2370,9 @@ principalmente sui server per evitare di mantenere impegnate le risorse che verrebbero dedicate a trattare delle connessioni che in realtà sono già terminate (quelle che vengono anche chiamate connessioni \textsl{semi-aperte}); in tutti quei casi cioè in cui il server si trova in -attesa di dati in ingresso su una connessione che non arriveranno mai perché o -il client sull'altro capo non è più attivo o non è più in grado di comunicare -con il server via rete. +attesa di dati in ingresso su una connessione che non arriveranno mai o perché +il client sull'altro capo non è più attivo o perché non è più in grado di +comunicare con il server via rete. \begin{figure}[!htb] \footnotesize \centering @@ -3048,11 +3067,11 @@ accessibili includendo detto file.\footnote{in realt numero massimo di ritrasmissioni del pacchetto SYN.\\ \const{TCP\_LINGER2} &$\bullet$&$\bullet$& &\texttt{int}& tempo di vita in stato \texttt{FIN\_WAIT2}.\\ - \const{TCP\_DEFER\_ACCEPT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + \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 \textit{advertised window}.\\ - \const{TCP\_INFO} &$\bullet$&? & &\struct{tcp\_info}& + \const{TCP\_INFO} &$\bullet$& & &\struct{tcp\_info}& raccoglie informazioni sul socket.\\ \const{TCP\_QUICKACK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& abilita la modalità \textit{quickack}.\\ @@ -3065,10 +3084,11 @@ accessibili includendo detto file.\footnote{in realt \label{tab:sock_opt_tcplevel} \end{table} -Le descrizioni riportata in tab.~\ref{tab:sock_opt_tcplevel} sono estremamente -sintetiche, una maggiore quantità di dettagli e la spiegazione delle singole -opzioni è fornita nel seguente elenco: -\begin{basedescript}{\desclabelwidth{3.0cm}\desclabelstyle{\nextlinelabel}} +Le descrizioni delle varie opzioni riportate in +tab.~\ref{tab:sock_opt_tcplevel} sono estremamente sintetiche, una maggiore +quantità di dettagli e la spiegazione delle singole opzioni è fornita nel +seguente elenco: +\begin{basedescript}{\desclabelwidth{3.3cm}\desclabelstyle{\nextlinelabel}} \item[\const{TCP\_NODELAY}] il protocollo TCP prevede, per evitare la trasmissione di tanti pacchetti piccoli, che comporta un utilizzo non @@ -3101,26 +3121,85 @@ opzioni punto tutti i dati rimasti in coda saranno inviati in un solo pacchetto. Questa opzione viene usata per gestire direttamente il flusso dei dati mettendo un ``\textsl{tappo}'' al flusso di uscita, in modo ottimizzare a - mano il throughput. - - Questa opzione non è disponibile su tutti i kernel unix-like e deve essere - evitata se si vuole avere codice portabile. - -\item[\const{TCP\_KEEPINTVL}] - -\item[\const{TCP\_KEEPCNT}] - -\item[\const{TCP\_SYNCNT}] - -\item[\const{TCP\_LINGER2}] + mano il throughput. È molto utile anche quando si effettua il trasferimento + di dati da un file con \func{sendfile} (vedi sez.~\ref{sec:file_sendfile}), + se si vuole inserire una intestazione prima della chiamata a questa + funzione. + + Si tenga presente che l'implementazione corrente di \const{TCP\_CORK} non + consente di bloccare l'invio dei pacchetti per più di 200 millisecondi, + passati i quali i dati accumulati in cosa sanno inviati comunque. Questa + opzione non è disponibile su tutti i kernel unix-like e deve essere evitata + se si vuole scrivere codice portabile. + +\item[\const{TCP\_KEEPIDLE}] imposta l'intervallo di tempo, in secondi, che + deve trascorrere senza traffico sul socket prima che vengano inviati, + qualora si sia attivata su di esso l'opzione \const{SO\_KEEPALIVE}, i + messaggi di \textit{keep-alive} (si veda la trattazione relativa al + \textit{keep-alive} in sez.~\ref{sec:sock_options_main}). Anche questa + opzione non è disponibile su tutti i kernel unix-like e deve essere evitata + se si vuole scrivere codice portabile. + +\item[\const{TCP\_KEEPINTVL}] imposta l'intervallo di tempo, in secondi, fra + due messaggi di \textit{keep-alive} successivi (si veda sempre quanto + illustrato in sez.~\ref{sec:sock_options_main}). Come la precedente non è + disponibile su tutti i kernel unix-like e deve essere evitata se si vuole + scrivere codice portabile. + +\item[\const{TCP\_KEEPCNT}] imposta il numero totale di messaggi di + \textit{keep-alive} da inviare prima di concludere che la connessione è + caduta (di nuovo vedi sez.~\ref{sec:sock_options_main}). Come la precedente + non è disponibile su tutti i kernel unix-like e deve essere evitata se si + vuole scrivere codice portabile. + +\item[\const{TCP\_SYNCNT}] imposta il numero di tentativi di ritrasmissione + dei segmenti SYN usati nel \itindex{three~way~handshake}\textit{three way + handshake} prima che il tentativo di connessione venga abortito (si + ricordi quanto accennato in sez.\ref{sec:TCP_func_connect}). Sovrascrive il + valore globale impostato con la \textit{sysctl} \texttt{tcp\_syn\_retries} + (vedi sez.~\ref{sec:sock_ipv4_sysctl}). Non vengono accettati valori + maggiori di 255; anche questa opzione non è standard e deve essere evitata + se si vuole scrivere codice portabile. + +\item[\const{TCP\_LINGER2}] imposta, in numero di secondi, il tempo di + sussistenza dei socket terminati nello stato \texttt{FIN\_WAIT2} (si ricordi + quanto visto in sez.~\ref{sec:TCP_conn_term}).\footnote{si tenga ben + presente che questa opzione non ha nulla a che fare con la + \const{SO\_LINGER} che abbiamo visto in sez.~\ref{sec:sock_options_main}.} + Questa opzione consente di sovrascrivere il valore globale impostato con la + \textit{sysctl} \texttt{tcp\_fin\_timeout} (vedi + sez.~\ref{sec:sock_ipv4_sysctl}). Anche questa opzione è da evitare se si + ha a cuore la portabilità del codice. + +\item[\const{TCP\_DEFER\_ACCEPT}] consente ad un socket in ascolto di + ritornare da \func{accept} soltanto quando sono presenti dati sullo stesso, + e non alla conclusione del \itindex{three~way~handshake} \textit{three way + handshake}. Prende un valore intero che indica il numero massimo di + secondi per cui il ritorno di \func{accept} viene rimandato; non deve essere + utilizzata in codice che vuole essere portabile. + +\item[\const{TCP\_WINDOW\_CLAMP}] limita 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 minima pari a \texttt{SOCK\_MIN\_RCVBUF/2}. Questa opzione + non deve essere utilizzata in codice che vuole essere portabile. + +\item[\const{TCP\_INFO}] permette di ricevere una serie di informazioni + relative al socket che il kernel restituisce in una speciale struttura + \struct{tcp\_info}, la cui definizione è riportata in + fig.~\ref{fig:tcp_info_struct}. -\item[\const{TCP\_DEFER\_ACCEPT}] - -\item[\const{TCP\_WINDOW\_CLAMP}] - -\item[\const{TCP\_INFO}] +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/tcp_info.h} + \end{minipage} + \caption{La struttura \structd{tcp\_info} contenente le informazioni sul + socket restituita dall'opzione \const{TCP\_INFO}.} + \label{fig:tcp_info_struct} +\end{figure} -\item[\const{TCP\_QUICKACK}] +\item[\const{TCP\_QUICKACK}] abilita la modalità speciale \textit{quickack}. \item[\const{TCP\_CONGESTION}] Introdotta con il kernel 2.6.13. @@ -3505,14 +3584,13 @@ sistema sotto \texttt{/proc/net}, dove sono presenti dei file che non corrispondono a nessun nodo di \func{sysctl}. - \subsection{I valori di controllo per i socket generici} \label{sec:sock_gen_sysctl} Nella directory \texttt{/proc/sys/net/core} sono presenti i file -corrispondenti ai parametri generici validi per tutti i socket. Quelli -descritti anche nella pagina di manuale, accessibile con \texttt{man 7 socket} -sono i seguenti: +corrispondenti ai parametri generici di \textit{sysctl} validi per tutti i +socket. Quelli descritti anche nella pagina di manuale, accessibile con +\texttt{man 7 socket} sono i seguenti: \begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}} \item[\texttt{rmem\_default}] imposta la dimensione di default del buffer di @@ -3605,7 +3683,7 @@ dello stesso (come ARP). I file che consentono di controllare le caratteristiche specifiche del protocollo IP in quanto tale, descritti anche nella pagina di manuale accessibile con \texttt{man 7 ip}, sono i seguenti: -\begin{basedescript}{\desclabelwidth{3.2cm}\desclabelstyle{\nextlinelabel}} +\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ò @@ -3666,9 +3744,89 @@ accessibile con \texttt{man 7 ip}, sono i seguenti: % \item[\texttt{neigh/*}] La directory contiene i valori % TODO trattare neigh/* nella parte su arp, da capire dove sarà. - \end{basedescript} +I file di \texttt{/proc/sys/net/ipv4} che invece fanno riferimento alle +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\_fin\_timeout}] specifica il numero di secondi (il default è + 60\footnote{nei kernel della serie 2.2.x era invece di 120 secondi.}) da + passare in stato \texttt{FIN\_WAIT2} nell'attesa delle ricezione del + pacchetto FIN conclusivo, passati quali il socket viene comunque chiuso + forzatamente. L'uso di questa opzione realizza quella che in sostanza è una + violazione delle specifiche del protocollo TCP, ma è utile per fronteggiare + 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\_max\_syn\_backlog}] un numero intero che indica la + lunghezza della coda delle connessioni incomplete, cioè delle connessioni + per le quali si è ricevuto un SYN di richiesta ma non l'ACK finale del + \itindex{three~way~handshake} \textit{three way handshake} (si riveda quanto + illustrato in sez.\ref{sec:TCP_func_listen}). + + Quando questo valore è superato il kernel scarterà immediatamente ogni + ulteriore richiesta di connessione. Il valore di default (che è 256) viene + automaticamente portato a 1024 qualora nel sistema ci sia sufficiente + memoria (se maggiore di 128Mb) e ridotto a 128 qualora la memoria sia poca + (inferiore a 32Mb).\footnote{si raccomanda, qualora si voglia aumentare il + valore oltre 1024, di seguire la procedura citata nella pagina di manuale + di TCP , e modificare il valore della costante \texttt{TCP\_SYNQ\_HSIZE} + nel file \texttt{include/net/tcp.h} dei sorgenti del kernel, in modo che + sia $\mathtt{tcp\_max\_syn\_backlog} \ge \mathtt{16*TCP\_SYNQ\_HSIZE}$, e + 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\_retrans\_collapse}] +\item[\texttt{tcp\_retries1}] + +\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}). + + +\item[\texttt{tcp\_rfc1337}] +\item[\texttt{tcp\_rmem}] +\item[\texttt{tcp\_sack}] +\item[\texttt{tcp\_stdurg}] +\item[\texttt{tcp\_synack\_retries}] +\item[\texttt{tcp\_syncookies}] + +\item[\texttt{tcp\_syn\_retries}] imposta il numero di tentativi (il default è + 5) di ritrasmissione dei pacchetti SYN di inizio connessione del + \itindex{three~way~handshake} \textit{three way handshake} (si ricordi + quanto illustrato in sez.\ref{sec:TCP_func_connect}). Il valore non deve + superare 255. + +\item[\texttt{tcp\_timestamps}] +\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}