\end{basedescript}
-\subsection{Le uso delle principali opzioni dei socket}
+\subsection{L'uso delle principali opzioni dei socket}
\label{sec:sock_options_main}
La descrizione sintetica del significato delle opzioni generiche dei socket,
-riportata nell'elenco in sez.~\ref{sec:sock_generic_options}, non è
-sufficientemente dettagliata per permetterci di approfondire tutti le
-funzionalità che alcune di esse possono controllare, alcune delle quali hanno
-un rilevanza notevole nella programmazione dei socket. Per questo motivo
-tratteremo nei dettagli le principali opzioni in questa sezione.
+riportata nell'elenco in sez.~\ref{sec:sock_generic_options}, è
+necessariamente sintentica, alcune di queste però possono essere utilizzate
+per controllare delle funzionalità che hanno una notevole rilevanza nella
+programmazione dei socket. Per questo motivo faremo in questa sezione un
+approfondimento sul significato delle opzioni generiche più importanti.
\index{\texttt{SO\_KEEPALIVE} (costante)|(}
sez.~\ref{sec:TCP_conn_crash} per il caso di terminazione prococe 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 si passa per
- la chiusura del processo, che chiude anche il socket inviando 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. In
-tal caso il socket viene chiuso dopo aver impostato un errore
-\errcode{ECONNRESET}.
+ 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 col'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}.
Se invece non viene ricevuta nessuna risposta (indice che la macchina non è
più raggiungibile) l'emissione dei messaggi viene ripetuta ad intervalli di 75
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\footnote{la terminazione di un processo di nuovo comporta la
- chiusura di tutti i file che aveva aperti e la relativa emissione degli
- opportuni segmenti FIN nel caso dei socket.} anche quando non si sta facendo
-traffico su di essa. In genere viene usata sui server per evitare di
-mantenere impegnate le risorse dedicate a trattare delle connessioni in realtà
-già terminate (quelle che vengono anche chiamate connessioni
-\textsl{semi-aperte}) in cui il server è in attesa di dati in ingresso che non
-arriveranno mai perché il client sull'altro capo non è più attivo.
-
-Abilitandola le connessioni effettivamente terminate vengono chiuse e ad
-esempio una \func{select} potrà rilevare la conclusione delle stesse e
-ricevere il relativo errore. Si tenga però presente che non si ha la certezza
-assoluta che un errore di \errcode{ETIMEDOUT} corrisponda ad una reale
-conclusione della connessione, il problema potrebbe essere dovuto ad un
-problema di routing che perduri per un tempo maggiore di quello impiegato nei
-vari tentativi di ritrasmissione del \textit{keep-alive} (anche se questa non
-è una una condizione molto probabile).
+In generale questa opzione serve per individuare una caduta della connessione
+anche quando non si sta facendo traffico su di essa. Viene usata
+principalmente sui server per evitare di mantenere impegnate le risorse che
+verrbbero 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.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:echod_keepalive_code}
\end{figure}
+Abilitandola dopo un certo tempo le connessioni effettivamente terminate
+verrano comunque chiuse per cui, utilizzando ad esempio una \func{select}, se
+be potrà rilevare la conclusione e ricevere il relativo errore. Si tenga
+presente però che non può avere la certezza assoluta che un errore di
+\errcode{ETIMEDOUT} ottenuto dopo aver abilitato questa opzione corrisponda
+necessariamente ad una reale conclusione della connessione, il problema
+potrebbe anche essere dovuto ad un problema di routing che perduri per un
+tempo maggiore di quello impiegato nei vari tentativi di ritrasmissione del
+\textit{keep-alive} (anche se questa non è una una condizione molto
+probabile).
+
Come esempio dell'utilizzo di questa opzione introduciamo all'interno del
nostro server per il servizio \textit{echo} la nuova opzione \texttt{-k} che
permette di attivare il \textit{keep-alive} sui socket; tralasciando la parte
la condizione (\texttt{\small 14}) che controlla l'attivazione del
\textit{keep-alive} che come valore dell'argomento \param{optval} della
chiamata a \func{setsockopt} (\texttt{\small 16}). A seconda del suo valore
-tutte le volta che un processo figlio viene eseguito in risposta ad una
+tutte le volte che un processo figlio viene eseguito in risposta ad una
connessione verrà pertanto eseguita o meno la sezione (\texttt{\small 14--17})
-che esegue l'impostazione di \const{SO\_KEEPALIVE} sul socket connesso.
+che esegue l'impostazione di \const{SO\_KEEPALIVE} sul socket connesso,
+attivando il relativo comportamento.
\index{\texttt{SO\_KEEPALIVE} (costante)|)}
sez.~\ref{sec:TCP_func_bind}, normalmente la funzione \func{bind} fallisce con
un errore di \errcode{EADDRINUSE} se la porta scelta è già utilizzata da un
altro socket, proprio per evitare che possano essere lanciati due server sullo
-stesso indirizzo che verrebbero a contendersi i relativi pacchetti.
-
-Esistono però dei casi speciali in cui non si vuole che questo accada, ed
-allora si può fare ricorso a questa opzione. La questione è comunque
-abbastanza complessa (il che rende questa una delle opzioni piu difficili da
-capire) in quanto, come sottolinea Stevens in \cite{UNP1}, si distinguono ben
-quattro casi diversi in cui è prevista la possibilità di un suo utilizzo.
-
-Il primo ed il più comune caso in cui si fa ricorso a \const{SO\_REUSEADDR} è
-quello in cui un server è terminato ma esistono ancora dei processi figli che
-mantengono attiva almeno una connessione remota che utilizza l'indirizzo
-locale mantenendo occupata la porta. Quando si riesegue il server allora
-questo riceve un errore sulla chiamata a \func{bind} dato che la porta è
-ancora utilizzata in una connessione esistente.\footnote{questa è una delle
- domande più frequenti sui newsgroup dedicati allo sviluppo, in quanto è
- piuttosto comune trovarsi in questa situazione quando si sta sviluppando un
- server che si ferma e si riavvia in continuazione dopo aver fatto
- modifiche.} Inoltre se si usa il protocollo TCP questo può avvenire anche
-dopo tutti i processi figlio sono terminati, dato che una connessione può
+stesso indirizzo e la stessa porta, che verrebbero a contendersi i pacchetti
+aventi quella destinazione.
+
+Esistono però situazioni ed esigenze particolari in cui non si vuole che
+questo comportamento di salvaguardia accada, ed allora si può fare ricorso a
+questa opzione. La questione è comunque abbastanza complessa in quanto, come
+sottolinea Stevens in \cite{UNP1}, si distinguono ben quattro casi diversi in
+cui è prevista la possibilità di un utilizzo di questa opzione, il che la
+rende una delle più difficili da capire.
+
+Il primo caso, che è anche il più comune, in cui si fa ricorso a
+\const{SO\_REUSEADDR} è quello in cui un server è terminato ma esistono ancora
+dei processi figli che mantengono attiva almeno una connessione remota che
+utilizza l'indirizzo locale, mantenendo occupata la porta. Quando si riesegue
+il server allora questo riceve un errore sulla chiamata a \func{bind} dato che
+la porta è ancora utilizzata in una connessione esistente.\footnote{questa è
+ una delle domande più frequenti sui newsgroup dedicati allo sviluppo, in
+ quanto è piuttosto comune trovarsi in questa situazione quando si sta
+ sviluppando un server che si ferma e si riavvia in continuazione dopo aver
+ fatto modifiche.} Inoltre se si usa il protocollo TCP questo può avvenire
+anche dopo tutti i processi figli sono terminati, dato che una connessione può
restare attiva anche dopo la chiusura del socket, mantenendosi nello stato
\texttt{TIME\_WAIT} (vedi sez.~\ref{sec:TCP_time_wait}).
Usando \const{SO\_REUSEADDR} fra la chiamata a \func{socket} e quella a
\func{bind} si consente a quest'ultima di avere comunque successo anche se la
connessione è attiva (o nello stato \texttt{TIME\_WAIT}). È bene però
-ricordare (si ricordi quanto detto in sez.~\ref{sec:TCP_time_wait}) che la
+ricordare (si riveda quanto detto in sez.~\ref{sec:TCP_time_wait}) che la
presenza dello stato \texttt{TIME\_WAIT} ha una ragione, ed infatti se si usa
questa opzione esiste sempre una probabilità, anche se estremamente
remota,\footnote{perché ciò avvenga infatti non solo devono coincidere gli
versione della funzione \func{sockbind} (vedi fig.~\ref{fig:sockbind_code})
che consenta l'impostazione di questa opzione. La nuova funzione è
\func{sockbindopt}, e le principali differenze rispetto alla precedente sono
-illustrate in fig.~\ref{fig:sockbindopt_code} dove si sono riportate le
-sezioni di codice modificate rispetto ad essa. Il codice completo della
-funzione si trova, insieme alle altre funzioni di servizio dei socket,
-all'interno del file \texttt{SockUtils.c} dei sorgenti allegati alla guida.
+illustrate in fig.~\ref{fig:sockbindopt_code}, dove si sono riportate le
+sezioni di codice modificate rispetto alla versione precedente. Il codice
+completo della funzione si trova, insieme alle altre funzioni di servizio dei
+socket, all'interno del file \texttt{SockUtils.c} dei sorgenti allegati alla
+guida.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:sockbindopt_code}
\end{figure}
-In realtà tutto quello che si è fatto è stato introdurre (\texttt{\small 1})
-un nuovo argomento intero \param{reuse} nella nuova funzione che conterrà il
+In realtà tutto quello che si è fatto è stato introdurre nella nuova funzione
+(\texttt{\small 1}) un nuovo argomento intero, \param{reuse}, che conterrà il
valore logico da usare nella successiva chiamata (\texttt{\small 14}) a
-\func{setsockopt}. Si è poi aggiunta la sezione (\texttt{\small 13-17}) che
+\func{setsockopt}. Si è poi aggiunta una sezione (\texttt{\small 13-17}) che
esegue l'impostazione dell'opzione fra la chiamata a \func{socket} e quella a
-\func{bind}.
+\func{bind}.
A questo punto basterà modificare il server per utilizzare la nuova
esiste, ma il comportamento di \const{SO\_REUSEADDR} è analogo, sarà cioè
possibile effettuare un \textit{completely duplicate binding} ed ottenere il
successo di \func{bind} su un socket legato allo stesso indirizzo e porta solo
-se il primo programma che ha eseguito \func{bind} su di essi ha impostato
+se il programma che ha eseguito per primo \func{bind} su di essi ha impostato
questa opzione.\footnote{Questa restrizione permette di evitare il cosiddetto
\textit{port stealing}, in cui un programma, usando \const{SO\_REUSEADDR},
può collegarsi ad una porta già in uso e ricevere i pacchetti destinati ad
un altro programma; con questa caratteristica ciò è possibile soltanto se il
primo programma a consentirlo, avendo usato fin dall'inizio
- \const{SO\_REUSEADDR}.}
+ \const{SO\_REUSEADDR}.}
+
\index{\texttt{SO\_REUSEADDR} (costante)|)}
esegue l'impostazione con questi valori sia \func{close} che \func{shutdown}
si bloccano, nel frattempo viene eseguita la normale procedura di conclusione
della connessione (quella di sez.~\ref{sec:TCP_conn_term}) ma entrambe le
-funzioni ritornano fintanto che non si sia concluso il procedimento di
+funzioni non ritornano fintanto che non si sia concluso il procedimento di
chiusura della connessione, o non sia passato un numero di
secondi\footnote{questa è l'unità di misura indicata da POSIX ed adottata da
Linux, altri kernel possono usare unità di misura diverse, oppure usare il
\label{tab:sock_opt_iplevel}
\end{table}
-
Le descrizioni di tab.~\ref{tab:sock_opt_iplevel} sono estremamente succinte,
una maggiore quantità di dettagli su queste opzioni è fornito nel seguente
elenco:
\begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}}
+
+
+\item[\const{IP\_OPTIONS}] l'opzione permette di impostare o leggere le
+ opzioni del protocollo IP (si veda sez.~\ref{sec:IP_options}). L'opzione
+ prende come valore dell'argomento \param{optval} un puntatore ad un buffer
+ dove sono mantenute le opzioni, mentre \param{optlen} indica la dimensione
+ di quest'ultimo. Quando la si usa con \func{setsockopt}
+
+\item[\const{IP\_PKTINFO}]
+
+\item[\const{IP\_RECVTOS}]
+
+\item[\const{IP\_RECVTTL}]
+
+\item[\const{IP\_RECVOPTS}]
+
+\item[\const{IP\_RETOPTS}]
+
+
+\item[\const{IP\_TOS}]
+
+
+\item[\const{IP\_TTL}]
+
+
+\item[\const{IP\_HDRINCL}]
+
+
+\item[\const{IP\_RECVERR}]
+
+\item[\const{IP\_MTU\_DISCOVER}]
+
+\item[\const{IP\_MTU}]
+
+\item[\const{IP\_ROUTER\_ALERT}]
+
+\item[\const{IP\_MULTICAST\_TTL}]
+
+
+
+
\item[\const{IP\_MULTICAST\_LOOP}] L'opzione consente di decidere se i dati
che si inviano su un socket usato con il multicast vengano ricevuti anche
sulla stessa macchina da cui li si stanno inviando. Prende per
disponibili l'uso di questa opzione permette di disabilitare questo tipo di
traffico.
+\item[\const{IP\_ADD\_MEMBERSHIP}]
+
+\item[\const{IP\_DROP\_MEMBERSHIP}]
+
+\item[\const{IP\_MULTICAST\_IF}]
+
+
\end{basedescript}