Ancora sulle opzioni dei socket generiche, aggiornando alcuni vecchi
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 26 Dec 2004 21:30:35 +0000 (21:30 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 26 Dec 2004 21:30:35 +0000 (21:30 +0000)
riferimenti sbagliati

sockctrl.tex
sources/mygetaddr.c
sources/mygethost.c
tcpsock.tex

index ee24c595e683aba08b9cd42ac44659797c7de0af..2b83e8429160762444323af645db82c4a609fa3a 100644 (file)
@@ -1872,29 +1872,37 @@ intende operare; per indicare l'opzione da impostare si devono usare i due
 argomenti successivi, \param{level} e \param{optname}.  Come abbiamo visto in
 sez.~\ref{sec:net_protocols} i protocolli di rete sono strutturati su vari
 livelli, ed l'interfaccia dei socket può usarne più di uno. Si avranno allora
-diverse funzionalità e caratteristiche per ciascun protocollo usato da un
-socket, e quindi saranno anche diverse le opzioni che di potranno impostare, a
-seconda del \textsl{livello} (trasporto, rete, ecc.)  su cui si va ad operare.
+funzionalità e caratteristiche diverse per ciascun protocollo usato da un
+socket, e quindi saranno anche diverse le opzioni che si potranno impostare
+per ciascun socket, a seconda del \textsl{livello} (trasporto, rete, ecc.) su
+cui si vuole andare ad operare.
 
 Il valore di \param{level} seleziona allora il protocollo su cui vuole
-intervenire, e permette di usare per \param{optname} i valori delle opzioni
-che sono definite su quel protocollo.  Esiste però anche il valore speciale
-\const{SOL\_SOCKET} che indica un livello di base e cioè le opzioni
-disponibili per qualunque tipo di socket.  Per impostare le opzioni relative
-alle funzionalità dei singoli protocolli si deve utilizzare il valore numerico
-che identifica questi ultimi in \file{/etc/protocols}; più comunemente si
-usano le apposite costanti \texttt{SOL\_*} riportate in
-tab.~\ref{tab:sock_option_levels}, dove si sono riassunti i valori possibili
-per l'argomento \param{level}.\footnote{la notazione in questo caso è,
-  purtroppo, abbastanza confusa: infatti in Linux il valore si può impostare
-  sia usando le costanti \texttt{SOL\_*}, che le analoghe \texttt{IPPROTO\_*}
-  (citate anche da Stevens in \cite{UNP1}); entrambe hanno gli stessi valori
-  che sono equivalenti ai numeri di protocollo di \file{/etc/protocols}, con
-  una eccesione specifica, che è quella del protocollo ICMP, per la quale non
+intervenire, mentre \param{optname} permette di scegliere su quale delle
+opzioni che sono definite per quel protocollo si vuole operare. In sostanza la
+selezione di una specifica opzione viene fatta attraverso una coppia di valori
+\param{level} e \param{optname} e chiaramente la funzione avrà successo
+soltanto se il protocollo in questione prevede quella opzione ed è utilizzato
+dal socket.  Infine \param{level} prevede anche il valore speciale
+\const{SOL\_SOCKET} usato per le opzioni generiche che sono disponibili per
+qualunque tipo di socket.
+
+I valori usati per \param{level}, corrispondenti ad un dato protocollo usato
+da un socket, sono quelli corrispondenti al valore numerico che identifica il
+suddetto protocollo in \file{/etc/protocols}; dato che la leggibilità di un
+programma non trarrebbe certo beneficio dall'uso diretto dei valori numerici,
+più comunemente si indica il protocollo tramite le apposite costanti
+\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels}, dove si sono
+riassunti i valori che possono essere usati per l'argomento
+\param{level}.\footnote{la notazione in questo caso è, purtroppo, abbastanza
+  confusa: infatti in Linux il valore si può impostare sia usando le costanti
+  \texttt{SOL\_*}, che le analoghe \texttt{IPPROTO\_*} (citate anche da
+  Stevens in \cite{UNP1}); entrambe hanno gli stessi valori che sono
+  equivalenti ai numeri di protocollo di \file{/etc/protocols}, con una
+  eccesione specifica, che è quella del protocollo ICMP, per la quale non
   esista una costante, il che è comprensibile dato che il suo valore, 1, è
   quello che viene assegnato a \const{SOL\_SOCKET}.}
 
-
 \begin{table}[!htb]
   \centering
   \footnotesize
@@ -1917,23 +1925,27 @@ per l'argomento \param{level}.\footnote{la notazione in questo caso 
 
 Il quarto argomento, \param{optval} è un puntatore ad una zona di memoria che
 contiene i dati che specificano il valore dell'opzione che si vuole passare al
-socket (e il tipo di dati varia a seconda dell'opzione), mentre l'ultimo
-argomento \param{optlen},\footnote{questo argomento è in realtà sempre di tipo
-  \ctyp{int}, come era nelle \acr{libc4} e \acr{libc5}; l'uso di
-  \ctyp{socklen\_t} è stato introdotto da POSIX (valgono le stesse
-  considerazioni per l'uso di questo tipo di dato fatte in
+socket, mentre l'ultimo argomento \param{optlen},\footnote{questo argomento è
+  in realtà sempre di tipo \ctyp{int}, come era nelle \acr{libc4} e
+  \acr{libc5}; l'uso di \ctyp{socklen\_t} è stato introdotto da POSIX (valgono
+  le stesse considerazioni per l'uso di questo tipo di dato fatte in
   sez.~\ref{sec:TCP_func_accept}) ed adottato dalle \acr{glibc}.} è la
 dimensione in byte dei dati presenti all'indirizzo indicato da \param{optval}.
+Dato che il tipo di dati varia a seconda dell'opzione scelta, occorrerà
+individuare qual'è quello che deve essere usato, ed utilizzare le opportune
+variabili.
 
 La gran parte delle opzioni utilizzano per \param{optval} un valore intero, se
-poi l'opzione esprime una condizione logica si deve usare particolare un
-valore non nullo per abilitarla ed un valore nullo per disabilitarla.  Se
-invece l'opzione non prevede di dover ricevere nessun tipo di valore si deve
-impostare \param{optval} a \const{NULL}. 
+poi l'opzione esprime una condizione logica, il valore è sempre un intero, am
+si dovrà usare un valore non nullo per abilitarla ed un valore nullo per
+disabilitarla.  Se invece l'opzione non prevede di dover ricevere nessun tipo
+di valore si deve impostare \param{optval} a \const{NULL}. Un piccolo numero
+di opzioni però usano dei tipi di dati peculiari, è questo il motivo per cui
+\param{optval} è stato definito come puntatore generico.
 
 La seconda funzione usata per controllare le proprietà dei socket è
-\func{getsockopt}, che serve a leggere i valori delle opzioni dd a farsi
-restituire i dati relativi al loro funzionamento; il suo prototipo è:
+\funcd{getsockopt}, che serve a leggere i valori delle opzioni dei socket ed a
+farsi restituire i dati relativi al loro funzionamento; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/socket.h}
   \headdecl{sys/types.h}
@@ -1956,29 +1968,270 @@ restituire i dati relativi al loro funzionamento; il suo prototipo 
 \end{functions}
 
 I primi tre argomenti sono identici ed hanno lo stesso significato di quelli
-di \func{setsockopt}, mentre \param{optval} in questo caso indica l'indirizzo
-a cui andranno scritti i dati letti dal socket, e \param{optlen} è usata come
-\textit{value result argument} per indicare la lunghezza del buffer allocato
-per \param{optval} e per ricevere indietro la dimensione effettiva dei dati
-scritti su di esso.
+di \func{setsockopt}, anche se non è detto che tutte le opzioni siano definite
+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 \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. Se la dimenzione del buffer allocato
+per \param{optval} non è sufficiente si avrà un errore.
+
 
 
 \subsection{Le opzioni generiche}
 \label{sec:sock_generic_options}
 
-Anche se ciascun tipo di socket presenta una serie di caratteristiche
-particolari, gestite attraverso delle opzioni specifiche, esiste un insieme
-generico di opzioni che possono applicarsi a qualunque tipo di
-socket.\footnote{una descrizione di queste opzioni è generalmente disponibile
-  nella quarta sezione delle pagine di manuale con \texttt{man 4 socket}.}
-Come detto in tal caso il livello da scegliere è \const{SOL\_SOCKET}
-
-
-
-In generale il valore di \param{optname} viene passato invariato al
+Come accennato esiste un insieme generico di opzioni dei socket che possono
+applicarsi a qualunque tipo di socket,\footnote{una descrizione di queste
+  opzioni è generalmente disponibile nella settima sezione delle pagine di
+  manuale, nel caso specifico la si può consultare con \texttt{man 7 socket}.}
+indipendentemente da quale protocollo venga poi utilizzato. Se si vuole
+operare su queste opzioni generiche il livello da utilizzare è
+\const{SOL\_SOCKET}; si è riportato un elenco di queste opzioni in
+tab.~\ref{tab:sock_opt_socklevel}.
 
 
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|c|c|c|l|l|}
+    \hline
+    \textbf{Opzione}&\texttt{get}&\texttt{set}&\textbf{flag}&\textbf{Tipo}&
+                    \textbf{Descrizione}\\
+    \hline
+    \hline
+    \const{SO\_KEEPALIVE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          controlla l'attività della connessione.\\
+    \const{SO\_OOBINLINE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          lascia in linea i dati \textit{out-of-band}.\\
+    \const{SO\_RCVLOWAT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          basso livello sul buffer di ricezione.\\
+    \const{SO\_SNDLOWAT} &$\bullet$&$\bullet$&         &\texttt{int}&
+                          basso livello sul buffer di trasmissione.\\
+    \const{SO\_RCVTIMEO} &$\bullet$&$\bullet$&         &\texttt{timeval}& 
+                          timeout in ricezione.\\
+    \const{SO\_SNDTIMEO} &$\bullet$&$\bullet$&         &\texttt{timeval}& 
+                          timeout in trasmissione.\\
+    \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          abilita la compatibilità con BSD.\\
+    \const{SO\_PASSCRED} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          abilita la ricezione di credenziali.\\
+    \const{SO\_PEERCRED} &$\bullet$&         &         &\texttt{ucred}& 
+                          restituisce le credenziali del processo remoto.\\
+    \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$&         &\texttt{char *}& 
+                          lega il socket ad un dispositivo.\\
+    \const{SO\_DEBUG}    &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          abilita il debugging sul socket.\\
+    \const{SO\_REUSEADDR}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          consente il riutilizzo di un indirizzo locale.\\
+    \const{SO\_TYPE}     &$\bullet$&         &         &\texttt{int}& 
+                          restituisce il tipo di socket.\\
+    \const{SO\_ACCEPTCONN}&$\bullet$&        &         &\texttt{int}& 
+                          indica se il socket è in ascolto.\\
+    \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          non invia attraverso un gateway.\\
+    \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& 
+                          attiva o disattiva il \textit{broadcast}.\\
+    \const{SO\_SNDBUF}   &$\bullet$&$\bullet$&         &\texttt{int}& 
+                          imposta dimensione del buffer di trasmissione.\\
+    \const{SO\_RCVBUF}   &$\bullet$&$\bullet$&         &\texttt{int}& 
+                          imposta dimensione del buffer di ricezione.\\
+    \const{SO\_LINGER}   &$\bullet$&$\bullet$&         &\texttt{linger}&
+                          indugia nella chiusura con dati da spedire.\\
+    \const{SO\_PRIORITY} &$\bullet$&$\bullet$&         &\texttt{int}& 
+                          imposta la priorità del socket.\\
+    \const{SO\_ERROR}    &$\bullet$&         &         &\texttt{int}& 
+                          riceve e cancella gli errori pendenti.\\
+   \hline
+  \end{tabular}
+  \caption{Le opzioni disponibili al livello \const{SOL\_SOCKET}.} 
+  \label{tab:sock_opt_socklevel}
+\end{table}
 
+La tabella elenca le costanti che identificano le singole opzioni da usare
+come valore per \param{optname}; le due colonne seguenti indicano per quali
+delle due funzioni (\func{getsockopt} o \func{setsockopt}) l'opzione è
+disponibile, mentre la colonna successiva indica, quando di ha a che fare con
+un valore di \param{optval} intero, se l'opzione è da considerare un numero o
+un valore logico. Si è inoltre riportato sulla quinta colonna il tipo di dato
+usato per \param{optval} ed una breve descrizione del significato delle
+singole opzioni sulla sesta.
+
+
+Dato che le descrizioni di tab.~\ref{tab:sock_opt_socklevel} sono estremamente
+sommarie, vale la pena entrare in dettagli maggiori; questo ci consentirà
+anche di trattare i vari casi particolari, dato che nonostante queste opzioni
+siano indicate al livello generico, alcune di esse han senso solo per alcuni
+tipi di socket. L'elenco dettagliato del significato di ciascuna di esse è
+allora il seguente:
+\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{SO\_KEEPALIVE}] una connessione può restare attiva senza che non
+  debba essere effettuato nessun traffico su di essa; in in certi casi può
+  essere utile controllarne lo stato per accorgersi di eventuali problemi, per
+  questo, se si imposta questa opzione, è 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 le connessioni (non ha senso per socket UDP ad
+  esempio), ed utilizza per \param{optval} un intero usato come valore logico.
+
+  L'opzione si applica principalmente ai socket TCP.  Con le impostazioni di
+  default (che sono riprese da BSD) Linux emette un messaggio di
+  \textit{keep-alive} verso l'altro capo della 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à; tutto
+  ciò viene effettuato dal 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 prococe del
+  server: il primo è quello in cui la macchina remota non riconosce più la
+  connessione, ad esempio perché ha avuto un crollo ed è stata
+  riavviata,\footnote{si ricordi che un normale riavvio non ha questo effetto,
+    in quanto si passa per la chiusura del processo che invia un segmento FIN
+    all'altro capo della connessione.} per cui si otterrà come risposta un
+  RST. 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 secondi ad 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 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}. Se invece si riceve in risposta ad uno di
+  questi messaggi un pacchetto ICMP di destinazione irraggiungibile verrà
+  restituito l'errore corrispondente.
+
+  In generale questa opzione serve per individuare un crash della macchina
+  all'altro capo della connessione,\footnote{il crash 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.} e viene usata
+  sui server per evitare di mantenere impegnate le risorse dedicate a trattare
+  delle connessioni in realtà terminate; abilitandola le connessioni
+  effettivamente terminate vengono chiuse ed 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}.
+
+
+
+\item[\const{SO\_OOBINLINE}] se questa opzione viene abilitata i dati
+  \textit{out-of-band} vengono inviati direttamente nel flusso di dati del
+  socket (e sono quindi letti con una normale \func{read}) invece che restare
+  disponibili solo per l'accesso con l'uso del flag \const{MSG\_OOB} di
+  \func{recvmsg}. Tratteremo l'argomento in dettaglio in
+  sez.~\ref{sec:TCP_urgent_data}. L'opzione funziona soltanto con socket che
+  supportino i dati \textit{out-of-band} (non ha senso per socket UDP ad
+  esempio), ed utilizza per \param{optval} un intero usato come valore logico.
+
+
+
+\item[\const{SO\_RCVLOWAT}] questa opzione imposta il valore che indica il
+  numero minimo di byte che devono essere presenti nel buffer di ricezione
+  perché il kernel passi i dati all'utente, restituendoli ad una \func{read} o
+  segnalando ad una \func{select} (vedi sez.~\ref{sec:TCP_sock_select}) che ci
+  sono dati in ingresso. L'opzione utilizza per \param{optval} un intero che
+  specifica il numero di byte, ma con Linux questo valore è sempre 1 e non può
+  essere cambiato; \func{getsockopt} leggerà questo valore mentre
+  \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}.
+
+
+\item[\const{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
+  numero minimo di byte che devono essere presenti nel buffer di scrittura
+  perché il kernel li invii al protocollo successivo, consentendo ad una
+  \func{write} di ritornare o segnalando ad una \func{select} (vedi
+  sez.~\ref{sec:TCP_sock_select}) che è possibile eseguire una scrittura.
+  L'opzione utilizza per \param{optval} un intero che specifica il numero di
+  byte, ma con Linux questo valore è sempre 1 e non può essere cambiato;
+  \func{getsockopt} leggerà questo valore mentre \func{setsockopt} darà un
+  errore di \errcode{ENOPROTOOPT}.
+
+
+\item[\const{SO\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
+  sulle operazioni di lettura da un socket, e prende per \param{optval} una
+  struttura di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct})
+  identica a quella usata con \func{select}. Con \func{getsockopt} si può
+  leggere il valore attuale, mentre con \func{setsockopt} si imposta il tempo
+  voluto, usando un valore nullo per \struct{timeval} il timeout viene
+  rimosso.
+
+  Se l'opzione viene attivata tutte le volte che una delle funzioni di lettura
+  (\func{read}, \func{readv}, \func{recv}, \func{recvfrom} e \func{recvmsg})
+  si blocca in attesa di dati per un tempo maggiore di quello impostato, essa
+  ritornerà un valore -1 e la variabile \var{errno} sarà impostata con un
+  errore di \errcode{EAGAIN} e \errcode{EWOULDBLOCK}, così come sarebbe
+  avvenuto se si fosse aperto il socket in modalità non bloccante.
+
+\item[\const{SO\_SNDTIMEO}] l'opzione permette di impostare un tempo massimo
+  sulle operazioni di scrittura su un socket, ed usa gli stessi valori di
+  \const{SO\_RCVTIMEO}.  In questo caso però si avrà un errore di
+  \errcode{EAGAIN} o \errcode{EWOULDBLOCK} per le funzioni di scrittura
+  \func{write}, \func{writev}, \func{send}, \func{sendfrom} e \func{sendmsg}
+  qualora queste restino bloccate per un tempo maggiore di quello specificato.
+
+\item[\const{SO\_BSDCOMPAT}] questa opzione abilita la compatibilità con il
+  comportamento di BSD (in particolare ne riproduce i bug).  Attualmente è una
+  opzione usata solo per il protocollo UDP e ne è prevista la rimozione in
+  futuro.  L'opzione utilizza per \param{optval} un intero usato come valore
+  logico.
+
+  Quando viene abilitata gli errori riportati da messaggi ICMP per un socket
+  UDP non vengono passati al programma in user space. Con le versioni 2.0.x
+  del kernel erano anche abilitate altre opzioni per i socket raw, che sono
+  state rimosse con il passaggio al 2.2; è consigliato correggere i programmi
+  piuttosto che usare questa funzione.
+
+\item[\const{SO\_PASSCRED}] questa opzione abilita la ricezione dei messaggi
+  di controllo \const{SCM\_CREDENTIALS} dei socket unix-domain. Prende per
+  \param{optval} un intero usato come valore logico.
+
+\item[\const{SO\_PEERCRED}] questa opzione restituisce le credenziali del
+  processo remoto connesso al socket; l'opzione è disponibile solo per socket
+  unix-domain e può essere usata solo con \func{getsockopt}.  Prende come
+  valore per \param{optval} una apposita struttura \struct{ucred} (vedi
+  sez.~\ref{sec:unix_socket_xxx}).
+
+\item[\const{SO\_BINDTODEVICE}] questa opzione permette di \textsl{legare} il
+  socket ad una particolare interfaccia interfaccia, in modo che esso possa
+  ricevere ed inviare pacchetti solo su quella. L'opzione richiede per
+  \param{optval} il puntatore ad una stringa contenente il nome
+  dell'interfaccia (ad esempio \texttt{eth0}); se si utilizza una stringa
+  nulla o un valore nullo per \param{optlen} si rimuove un precedente
+  collegamento.
+
+  Il nome della interfaccia deve essere specificato con una stringa terminata
+  da uno zero e di lunghezza massima pari a \const{IFNAMSIZ}; l'opzione è
+  effettiva solo per alcuni tipi di socket, ed in particolare per quelli della
+  famiglia \const{AF\_INET}; non è invece supportata per i \textit{packet
+    socket} (vedi sez.~\ref{cha:advanced_socket_xxx}).
+
+
+\item[\const{SO\_DEBUG}] 
+
+\item[\const{SO\_REUSEADDR}]
+
+\item[\const{SO\_TYPE}] questa opzione permette di leggere il tipo di socket
+  su cui si opera; funziona solo con \func{getsockopt}, ed utilizza per
+  \param{optval} un valore intero in cui verrà restituto il valore numerico
+  che lo identifica (ad esempio \const{SOCK\_STREAM}).
+
+\item[\const{SO\_ACCEPTCONN}]
+\item[\const{SO\_DONTROUTE}]
+\item[\const{SO\_BROADCAST}]
+\item[\const{SO\_SNDBUF}]
+\item[\const{SO\_RCVBUF}]  
+\item[\const{SO\_LINGER}]  
+\item[\const{SO\_PRIORITY}]
+\item[\const{SO\_ERROR}]
+\end{basedescript}
 
 
 
index b33f9c29db379154602a29a6896fdec5578ad326..3f51313925df35744d01633e6cb0deb5ee0136c3 100644 (file)
@@ -38,9 +38,9 @@
 
 #include "Gapil.h"
 /*
- * Program myhost
+ * Program mygetaddr
  *
- * Use gethostbyname and print results
+ * Use getaddrinfo and print results
  */
 /* Help printing routine */
 void usage(void);
index 76cf84477eb5edd568c52c40bf3d6199b30dfb1a..11ae1cef264f4bbbfd36d9c071ccf3b9713af635 100644 (file)
@@ -36,7 +36,7 @@ extern int h_errno;
 
 #include "Gapil.h"
 /*
- * Program myhost
+ * Program mygethost
  *
  * Use gethostbyname and print results
  */
@@ -50,6 +50,18 @@ int main(int argc, char *argv[])
  */
     int i;
     struct hostent *data;
+
+    struct sock_level {
+       int level;
+       char * name;
+    } sock_level[] = {
+       SOL_SOCKET, "SOL_SOCKET",
+       SOL_IP,     "SOL_IP",
+       SOL_TCP,    "SOL_TCP",
+       SOL_IPV6,   "SOL_IPV6",
+       SOL_ICMPV6, "SOL_ICMPV6"
+    };
+
     char **alias;
     char *addr;
     char buffer[INET6_ADDRSTRLEN];
index ad5e2056685f04fe939aae1bc1db38698ac35c62..b13c16dd008674252539a5685288e362a2c80aec 100644 (file)
@@ -2581,15 +2581,15 @@ successivo, per tentare di ristabilire la connessione.
 Il risultato finale qui dipende dall'implementazione dello stack TCP, e nel
 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}. 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 riportato all'uscita del client non è stato
-\errcode{ETIMEDOUT}, come dovrebbe essere in questo caso, ma
-\errcode{EHOSTUNREACH}.
+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
+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
+riportato all'uscita del client non è stato \errcode{ETIMEDOUT}, come dovrebbe
+essere in questo caso, ma \errcode{EHOSTUNREACH}.
 
 Per capire l'accaduto continuiamo ad analizzare l'output di \cmd{tcpdump}:
 esso ci mostra che a un certo punto i tentativi di ritrasmissione del
@@ -2700,7 +2700,7 @@ riportando appunto come errore \errcode{ECONNRESET}. Occorre precisare che se
 si vuole che il client sia in grado di accorgersi del crollo del server anche
 quando non sta effettuando uno scambio di dati, è possibile usare una
 impostazione speciale del socket (ci torneremo in
-sez.~\ref{sec:TCP_sock_options}) che provvede all'esecuzione di questo
+sez.~\ref{sec:sock_generic_options}) che provvede all'esecuzione di questo
 controllo.
 
 \section{L'uso dell'I/O multiplexing}
@@ -2748,8 +2748,8 @@ pronto per la lettura sono le seguenti:
   sufficiente a superare il valore di una \textsl{soglia di basso livello} (il
   cosiddetto \textit{low watermark}). Questo valore è espresso in numero di
   byte e può essere impostato con l'opzione del socket \const{SO\_RCVLOWAT}
-  (tratteremo le opzioni dei socket in sez.~\ref{sec:TCP_sock_options}); il
-  suo valore di default è 1 per i socket TCP e UDP. In questo caso una
+  (tratteremo l'uso di questa opzione in sez.~\ref{sec:sock_generic_options});
+  il suo valore di default è 1 per i socket TCP e UDP. In questo caso una
   operazione di lettura avrà successo e leggerà un numero di byte maggiore di
   zero.
 \item il lato in lettura della connessione è stato chiuso; si è cioè ricevuto
@@ -2761,7 +2761,7 @@ pronto per la lettura sono le seguenti:
 \item c'è stato un errore sul socket. In questo caso una operazione di lettura
   non si bloccherà ma restituirà una condizione di errore (ad esempio
   \func{read} restituirà -1) e imposterà la variabile \var{errno} al relativo
-  valore. Vedremo in sez.~\ref{sec:TCP_sock_options} come sia possibile
+  valore. Vedremo in sez.~\ref{sec:sock_generic_options} come sia possibile
   estrarre e cancellare errori pendenti su un socket usando l'opzione
   \const{SO\_ERROR}.
 \item quando si sta utilizzando un \textit{listening socket} ed ci sono delle
@@ -2782,8 +2782,9 @@ pronto per la scrittura sono le seguenti:
   valore della \textsl{soglia di basso livello} in scrittura ed inoltre o il
   socket è già connesso o non necessita (ad esempio è UDP) di connessione.  Il
   valore della soglia è espresso in numero di byte e può essere impostato con
-  l'opzione del socket \const{SO\_SNDLOWAT}; il suo valore di default è 2048
-  per i socket TCP e UDP. In questo caso una operazione di scrittura non si
+  l'opzione del socket \const{SO\_SNDLOWAT} (trattata in
+  sez.~\ref{sec:sock_generic_options}); il suo valore di default è 2048 per i
+  socket TCP e UDP. In questo caso una operazione di scrittura non si
   bloccherà e restituirà un valore positivo pari al numero di byte accettati
   dal livello di trasporto.
 \item il lato in scrittura della connessione è stato chiuso. In questo caso
@@ -2791,7 +2792,7 @@ pronto per la scrittura sono le seguenti:
 \item c'è stato un errore sul socket. In questo caso una operazione di
   scrittura non si bloccherà ma restituirà una condizione di errore ed
   imposterà opportunamente la variabile \var{errno}. Vedremo in
-  sez.~\ref{sec:TCP_sock_options} come sia possibile estrarre e cancellare
+  sez.~\ref{sec:sock_generic_options} come sia possibile estrarre e cancellare
   errori pendenti su un socket usando l'opzione \const{SO\_ERROR}.
 \end{itemize*}