X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sockctrl.tex;h=585e3712e22092777a4b6d4420ef063be881524e;hp=b0cc66c6b02f34a8a346a30865f74858a5742ca5;hb=6f8e0ca42d3d0b97b5e5747798a1eaffb44e8521;hpb=b8a1f2a162b832eb587152b245309d8f86ddd10e diff --git a/sockctrl.tex b/sockctrl.tex index b0cc66c..585e371 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -34,13 +34,13 @@ porte o altre propriet \subsection{La struttura del \textit{resolver}} \label{sec:sock_resolver} -\index{\textit{resolver}|(} +\itindbeg{resolver} La risoluzione dei nomi è associata tradizionalmente al servizio del \textit{Domain Name Service} che permette di identificare le macchine su internet invece che per numero IP attraverso il relativo \textsl{nome a dominio}.\footnote{non staremo ad entrare nei dettagli della definizione di cosa è un nome a dominio, dandolo per noto, una introduzione alla - problematica si trova in \cite{AGL} (cap. 9) mentre per una trattazione + problematica si trova in \cite{AGL} (cap.~9) mentre per una trattazione approfondita di tutte le problematiche relative al DNS si può fare riferimento a \cite{DNSbind}.} In realtà per DNS si intendono spesso i server che forniscono su internet questo servizio, mentre nel nostro caso @@ -117,7 +117,7 @@ dell'ordine in cui questi vengono interrogati.\footnote{con le implementazioni funzioni di libreria, prevedendo un ordine di interrogazione predefinito e non modificabile (a meno di una ricompilazione delle librerie stesse).} -\index{\textit{Name~Service~Switch}|(} +\itindbeg{Name~Service~Switch} Per risolvere questa serie di problemi la risoluzione dei nomi a dominio eseguirà dal \textit{resolver} è stata inclusa all'interno di un meccanismo generico per la risoluzione di corrispondenze fra nomi ed informazioni ad essi @@ -147,7 +147,7 @@ tab.~\ref{tab:sys_NSS_classes}. (\acr{uid}, ecc.).\\ \texttt{group} & corrispondenze fra nome del gruppo e proprietà dello stesso.\\ - \texttt{aliases} & alias per la posta elettronica\\ + \texttt{aliases} & alias per la posta elettronica.\\ \texttt{ethers} & corrispondenze fra numero IP e MAC address della scheda di rete.\\ \texttt{hosts} & corrispondenze fra nome a dominio e numero IP.\\ @@ -168,7 +168,7 @@ tab.~\ref{tab:sys_NSS_classes}. \label{tab:sys_NSS_classes} \end{table} -Il sistema del \textit{Name Service Switch} è controllato dal contenuto del +Il sistema del \textit{Name Service Switch} è controllato dal contenuto del file \file{/etc/nsswitch.conf}; questo contiene una riga\footnote{seguendo una convezione comune per i file di configurazione le righe vuote vengono ignorate e tutto quello che segue un carattere ``\texttt{\#}'' viene @@ -193,7 +193,7 @@ quello che conta sono le funzioni classiche che il \textit{resolver} mette a disposizione,\footnote{è cura della implementazione fattane nelle \acr{glibc} tenere conto della presenza del \textit{Name Service Switch}.} e sono queste quelle che tratteremo nelle sezioni successive. -\index{\textit{Name~Service~Switch}|)} +\itindend{Name~Service~Switch} \subsection{Le funzioni di interrogazione del \textit{resolver}} @@ -610,16 +610,15 @@ Restituisce una stringa corrispondente ad un errore di risoluzione. \noindent che, come l'analoga \func{strerror}, restituisce una stringa con un messaggio di errore già formattato, corrispondente al codice passato come argomento (che si presume sia dato da \var{h\_errno}). -\index{\textit{resolver}|)} - +\itindend{resolver} \subsection{La risoluzione dei nomi a dominio} \label{sec:sock_name_services} -La principale funzionalità del \index{\textit{resolver}}\textit{resolver} -resta quella di risolvere i nomi a dominio in indirizzi IP, per cui non ci +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 scopo è ottenere l'indirizzo di una stazione noto il suo nome a dominio, il @@ -683,7 +682,7 @@ Con l'uso di \func{gethostbyname} normalmente si ottengono solo gli indirizzi 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 \index{\textit{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 è: @@ -720,10 +719,10 @@ suoi risultati. 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 -\index{\textit{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. +\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. Il programma richiede un solo argomento che specifichi il nome da cercare, senza il quale (\texttt{\small 12--15}) esce con un errore. Dopo di che @@ -778,10 +777,10 @@ copiare il contenuto della sola struttura non 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 -\index{\textit{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 +\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.} @@ -819,9 +818,9 @@ lunghezza di questo buffer devono essere indicati con gli argomenti \param{buf} e \param{buflen}. Gli ultimi due argomenti vengono utilizzati per avere indietro i risultati -come \index{\textit{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 +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}. In caso di successo entrambe le funzioni restituiscono un valore nullo, @@ -883,17 +882,18 @@ usare la funzione \funcd{gethostbyaddr}, il cui prototipo In questo caso l'argomento \param{addr} dovrà essere il puntatore ad una appropriata struttura contenente il valore dell'indirizzo IP (o IPv6) che si -vuole risolvere. L'uso del tipo \type{char *} per questo argomento è storico, -il dato dovrà essere fornito in una struttura \struct{in\_addr}\footnote{si - ricordi che, come illustrato in fig.~\ref{fig:sock_sa_ipv4_struct}, questo - in realtà corrisponde ad un numero intero, da esprimere comunque in - \textit{network order}, non altrettanto avviene però per \var{in6\_addr}, - pertanto è sempre opportuno inizializzare questi indirizzi con - \func{inet\_pton} (vedi sez.~\ref{sec:sock_conv_func_gen}).} per un -indirizzo IPv4 ed una struttura \struct{in6\_addr} per un indirizzo IPv6, -mentre in \param{len} se ne dovrà specificare la dimensione (rispettivamente 4 -o 16), infine l'argomento \param{type} indica il tipo di indirizzo e dovrà -essere o \const{AF\_INET} o \const{AF\_INET6}. +vuole risolvere. L'uso del tipo \texttt{char *} per questo argomento è +storico, il dato dovrà essere fornito in una struttura +\struct{in\_addr}\footnote{si ricordi che, come illustrato in + fig.~\ref{fig:sock_sa_ipv4_struct}, questo in realtà corrisponde ad un + numero intero, da esprimere comunque in \textit{network order}, non + altrettanto avviene però per \struct{in6\_addr}, pertanto è sempre opportuno + inizializzare questi indirizzi con \func{inet\_pton} (vedi + sez.~\ref{sec:sock_conv_func_gen}).} per un indirizzo IPv4 ed una struttura +\struct{in6\_addr} per un indirizzo IPv6, mentre in \param{len} se ne dovrà +specificare la dimensione (rispettivamente 4 o 16), infine l'argomento +\param{type} indica il tipo di indirizzo e dovrà essere o \const{AF\_INET} o +\const{AF\_INET6}. La funzione restituisce, in caso di successo, un puntatore ad una struttura \struct{hostent}, solo che in questo caso la ricerca viene eseguita @@ -969,7 +969,7 @@ tab.~\ref{tab:sock_getipnodebyname_flags}. sistema è associata ad un indirizzo di tale tipo.\\ \const{AI\_DEFAULT} & il valore di default, è equivalente alla combinazione di \const{AI\_ADDRCONFIG} e di - \const{AI\_V4MAPPED)}.\\ + \const{AI\_V4MAPPED}.\\ \hline \end{tabular} \caption{Valori possibili per i bit dell'argomento \param{flags} della @@ -1173,9 +1173,9 @@ rimandando alle rispettive pagine di manuale. \textbf{Informazione}&\multicolumn{3}{|c|}{\textbf{Funzioni}}\\ \hline \hline - indirizzo&\func{sethostent}&\func{gethostent}&\func{endhostent} \\ - servizio &cd te\func{setservent}&\func{getservent}&\func{endservent}\\ - rete &\func{setnetent}&\func{getnetent}&\func{endnetent}\\ + indirizzo &\func{sethostent} &\func{gethostent} &\func{endhostent} \\ + servizio &\func{setservent} &\func{getservent} &\func{endservent}\\ + rete &\func{setnetent} &\func{getnetent} &\func{endnetent}\\ protocollo&\func{setprotoent}&\func{getprotoent}&\func{endprotoent}\\ \hline \end{tabular} @@ -1248,6 +1248,16 @@ ricerche generiche sugli indirizzi, usando sia IPv4 che IPv6, e richiedere risoluzioni sui nomi dei servizi indipendentemente dal protocollo (ad esempio TCP o UDP) che questi possono utilizzare. +Come ultimo argomento in \param{res} deve essere passato un puntatore ad una +variabile (di tipo puntatore ad una struttura \struct{addrinfo}) che verrà +utilizzata dalla funzione per riportare (come \itindex{value~result~argument} +\textit{value result argument}) i propri risultati. La funzione infatti è +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 +\struct{addrinfo} contenenti tutte le informazioni ottenute. + \begin{figure}[!htb] \footnotesize \centering \begin{minipage}[c]{15cm} @@ -1258,12 +1268,12 @@ TCP o UDP) che questi possono utilizzare. \label{fig:sock_addrinfo_struct} \end{figure} -La struttura \struct{addrinfo}, la cui definizione\footnote{la definizione è - ripresa direttamente dal file \texttt{netdb.h} in questa struttura viene - dichiarata, la pagina di manuale riporta \type{size\_t} come tipo di dato - per il campo \var{ai\_addrlen}, qui viene usata quanto previsto dallo - standard POSIX, in cui viene utilizzato \type{socklen\_t}; i due tipi di - dati sono comunque equivalenti.} è riportata in +Come illustrato la struttura \struct{addrinfo}, la cui definizione\footnote{la + definizione è ripresa direttamente dal file \texttt{netdb.h} in questa + struttura viene dichiarata, la pagina di manuale riporta \type{size\_t} come + tipo di dato per il campo \var{ai\_addrlen}, qui viene usata quanto previsto + dallo standard POSIX, in cui viene utilizzato \type{socklen\_t}; i due tipi + di dati sono comunque equivalenti.} è riportata in fig.~\ref{fig:sock_addrinfo_struct}, viene usata sia in ingresso, per passare dei valori di controllo alla funzione, che in uscita, per ricevere i risultati. Il primo campo, \var{ai\_flags}, è una maschera binaria di bit che @@ -1273,7 +1283,7 @@ che viene usato soltanto in ingresso. I tre campi successivi \var{ai\_family}, famiglia di indirizzi, il tipo di socket e il protocollo, in ingresso vengono usati per impostare una selezione (impostandone il valore nella struttura puntata da \param{hints}), mentre in uscita indicano il tipo di risultato -contenuto nella struttura. +contenuto nella struttura. Tutti i campi seguenti vengono usati soltanto in uscita; il campo \var{ai\_addrlen} indica la dimensione della struttura degli indirizzi @@ -1364,15 +1374,6 @@ bit della maschera. \label{tab:ai_flags_values} \end{table} -Come ultimo argomento di \func{getaddrinfo} deve essere passato un puntatore -ad una variabile (di tipo puntatore ad una struttura \struct{addrinfo}) che -verrà utilizzata dalla funzione per riportare (come \textit{value result - argument}) i propri risultati. La funzione infatti è rientrante, ed alloca -autonomamente tutta la memoria necessaria in cui verranno riportati i -risultati della risoluzione. La funzione scriverà in \param{res} il puntatore -iniziale ad una \index{\textit{linked~list}}\textit{linked list} di strutture -di tipo \struct{addrinfo} contenenti tutte le informazioni ottenute. - La funzione restituisce un valore nullo in caso di successo, o un codice in caso di errore. I valori usati come codice di errore sono riportati in tab.~\ref{tab:addrinfo_error_code}; dato che la funzione utilizza altre @@ -1414,7 +1415,7 @@ corrispondente \const{EAI\_SYSTEM} & c'è stato un errore di sistema, si può controllare \var{errno} per i dettagli. \\ % \hline -% estensioni GNU, trovarne la documentazione +% TODO estensioni GNU, trovarne la documentazione % \const{EAI\_INPROGRESS}& richiesta in corso. \\ % \const{EAI\_CANCELED}& la richiesta è stata cancellata.\\ % \const{EAI\_NOTCANCELED}& la richiesta non è stata cancellata. \\ @@ -1461,14 +1462,14 @@ lista illustrata in fig.~\ref{fig:sock_addrinfo_list}. \begin{figure}[!htb] \centering \includegraphics[width=10cm]{img/addrinfo_list} - \caption{La \index{\textit{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 \index{\textit{resolver}}\textit{resolver} -basato questa funzione, il cui corpo principale è riportato in +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 dell'argomento \var{hints} per restringere le ricerche su protocolli, tipi di @@ -1558,11 +1559,10 @@ IPv4 address: \end{Verbatim} %$ -Una volta estratti i risultati dalla -\index{\textit{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 è: +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 è: \begin{functions} \headdecl{netdb.h} @@ -1581,7 +1581,7 @@ per \param{res}. 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 \index{\textit{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. @@ -1979,11 +1979,12 @@ di \func{setsockopt}, anche se non 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. +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. +Se la dimenzione del buffer allocato per \param{optval} non è sufficiente si +avrà un errore. @@ -2136,7 +2137,7 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni: consente però di impostare il timout per l'uso di \func{connect}, per avere il quale si può ricorrere a questa opzione. -% verificare con un programma di test +% TODO verificare il timeout con un programma di test \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 @@ -2184,21 +2185,21 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni: \item[\const{SO\_DEBUG}] questa opzione abilita il debugging delle operazioni dei socket; l'opzione utilizza per \param{optval} un intero usato come valore logico, e può essere utilizzata solo da un processo con i privilegi - di amministratore (in particolare con la \textit{capability} - \const{CAP\_NET\_ADMIN}). L'opzione necessita inoltre dell'opportuno - supporto nel kernel;\footnote{deve cioè essere definita la macro di - preprocessore \macro{SOCK\_DEBUGGING} nel file \file{include/net/sock.h} - dei sorgenti del kernel, questo è sempre vero nei kernel delle serie - superiori alla 2.3, per i kernel delle serie precedenti invece è - necessario aggiungere a mano detta definizione; è inoltre possibile - abilitare anche il tracciamento degli stati del TCP definendo la macro - \macro{STATE\_TRACE} in \file{include/net/tcp.h}.} quando viene - abilitata una serie di messaggi con le informazioni di debug vengono inviati - direttamente al sistema del kernel log.\footnote{si tenga presente che il - comportamento è diverso da quanto avviene con BSD, dove l'opzione opera - solo sui socket TCP, causando la scrittura di tutti i pacchetti inviati - sulla rete su un buffer circolare che viene letto da un apposito - programma, \cmd{trpt}.} + di amministratore (in particolare con la \itindex{capabilities} + \textit{capability} \const{CAP\_NET\_ADMIN}). L'opzione necessita inoltre + dell'opportuno supporto nel kernel;\footnote{deve cioè essere definita la + macro di preprocessore \macro{SOCK\_DEBUGGING} nel file + \file{include/net/sock.h} dei sorgenti del kernel, questo è sempre vero + nei kernel delle serie superiori alla 2.3, per i kernel delle serie + precedenti invece è necessario aggiungere a mano detta definizione; è + inoltre possibile abilitare anche il tracciamento degli stati del TCP + definendo la macro \macro{STATE\_TRACE} in \file{include/net/tcp.h}.} + quando viene abilitata una serie di messaggi con le informazioni di debug + vengono inviati direttamente al sistema del kernel log.\footnote{si tenga + presente che il comportamento è diverso da quanto avviene con BSD, dove + l'opzione opera solo sui socket TCP, causando la scrittura di tutti i + pacchetti inviati sulla rete su un buffer circolare che viene letto da un + apposito programma, \cmd{trpt}.} \item[\const{SO\_REUSEADDR}] questa opzione permette di eseguire la funzione \func{bind} su indirizzi locali che siano già in uso da altri socket; @@ -2262,9 +2263,10 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni: per primi, in modalità che dipendono dalla disciplina di gestione della coda. Nel caso di protocollo IP questa opzione permette anche di impostare i valori del campo \textit{type of service} (noto come TOS, vedi - sez.~\ref{sec:IP_xxx}) per i pacchetti uscenti. Per impostare una priorità - al di fuori dell'intervallo di valori fra 0 e 6 sono richiesti i privilegi - di amministratore con la capability \const{CAP\_NET\_ADMIN}. + sez.~\ref{sec:IP_header}) per i pacchetti uscenti. Per impostare una + priorità al di fuori dell'intervallo di valori fra 0 e 6 sono richiesti i + privilegi di amministratore con la \itindex{capabilities} capability + \const{CAP\_NET\_ADMIN}. \item[\const{SO\_ERROR}] questa opzione riceve un errore presente sul socket; può essere utilizzata soltanto con \func{getsockopt} e prende per @@ -2272,18 +2274,18 @@ tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni: \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)|(} +\index{costante!{SO\_KEEPALIVE}@{{\tt {SO\_KEEPALIVE}}}|(} \subsubsection{L'opzione \const{SO\_KEEPALIVE}} La prima opzione da approfondire è \const{SO\_KEEPALIVE} che permette di @@ -2312,13 +2314,14 @@ In caso di problemi invece si possono avere i due casi gi 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 @@ -2334,24 +2337,15 @@ 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\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 @@ -2365,6 +2359,16 @@ vari tentativi di ritrasmissione del \textit{keep-alive} (anche se questa non \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 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 @@ -2378,13 +2382,15 @@ Come si pu 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. -\index{\texttt{SO\_KEEPALIVE} (costante)|)} +che esegue l'impostazione di \const{SO\_KEEPALIVE} sul socket connesso, +attivando il relativo comportamento. +\index{costante!{SO\_KEEPALIVE}@{{\tt {SO\_KEEPALIVE}}}|)} + -\index{\texttt{SO\_REUSEADDR} (costante)|(} +\index{costante!{SO\_REUSEADDR}@{{\tt {SO\_REUSEADDR}}}|(} \subsubsection{L'opzione \const{SO\_REUSEADDR}} La seconda opzione da approfondire è \const{SO\_REUSEADDR}, che consente di @@ -2393,32 +2399,34 @@ uso da parte di un altro socket. Si ricordi infatti che, come accennato in 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 @@ -2431,10 +2439,11 @@ Come esempio di uso di questa connessione abbiamo predisposto una nuova 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 @@ -2447,12 +2456,12 @@ all'interno del file \texttt{SockUtils.c} dei sorgenti allegati alla guida. \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 @@ -2508,7 +2517,7 @@ il sistema non supporta l'opzione \const{IP\_RECVDSTADDR};\footnote{nel caso sviluppo del kernel 2.1.x, ma è in seguito stata soppiantata dall'uso di \const{IP\_PKTINFO} (vedi sez.~\ref{sec:sock_ipv4_options}).} in tale modo si può sapere a quale socket corrisponde un certo indirizzo. Non ha senso -fare questa operazionie per socket TCP dato che su di essi si può sempre +fare questa operazione per un socket TCP dato che su di essi si può sempre invocare \func{getsockname} una volta che si è completata la connessione. Infine il quarto caso è quello in cui si vuole effettivamente ottenere un @@ -2545,17 +2554,17 @@ opzione sia specificata per tutti i socket per i quali si vuole eseguire il 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}.} -\index{\texttt{SO\_REUSEADDR} (costante)|)} + \const{SO\_REUSEADDR}.} +\index{costante!{SO\_REUSEADDR}@{{\tt {SO\_REUSEADDR}}}|)} -\index{\texttt{SO\_LINGER} (costante)|(} +\index{costante!{SO\_LINGER}@{{\tt {SO\_LINGER}}}|(} \subsubsection{L'opzione \const{SO\_LINGER}} La terza opzione da approfondire è \const{SO\_LINGER}; essa, come il nome @@ -2632,7 +2641,7 @@ Infine l'ultima possibilit 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 @@ -2641,9 +2650,7 @@ secondi\footnote{questa completamento della trasmissione dei dati sul buffer.} pari al valore specificato in \var{l\_linger}. - - -\index{\texttt{SO\_LINGER} (costante)|)} +\index{costante!{SO\_LINGER}@{{\tt {SO\_LINGER}}}|)} @@ -2658,7 +2665,9 @@ socket che usano il protocollo IPv4.\footnote{come per le precedenti opzioni pagine di manuale, nel caso specifico la documentazione si può consultare con \texttt{man 7 ip}.} Se si vuole operare su queste opzioni generiche il livello da utilizzare è \const{SOL\_IP}; si è riportato un elenco di queste -opzioni in tab.~\ref{tab:sock_opt_iplevel}. +opzioni in tab.~\ref{tab:sock_opt_iplevel}. Le costanti indicanti le opzioni e +tutte le altre costanti ad esse collegate sono definite in +\file{netinet/ip.h}, ed accessibili includendo detto file. \begin{table}[!htb] @@ -2670,57 +2679,186 @@ opzioni in tab.~\ref{tab:sock_opt_iplevel}. \textbf{Descrizione}\\ \hline \hline - \const{IP\_OPTIONS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Imposta o riceve le opzioni di IP.\\ - \const{IP\_PKTINFO}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Passa un messaggio di informazione.\\ - \const{IP\_RECVTOS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Passa un messaggio col campo TOS.\\ - \const{IP\_RECVTTL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Passa un messaggio col campo TTL.\\ - \const{IP\_RECVOPTS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Passa un messaggio con le opzioni IP.\\ - \const{IP\_RETOPTS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Passa un messaggio con le opzioni IP non - trattate.\\ - \const{IP\_TOS}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Imposta il valore del campo TOS.\\ - \const{IP\_TTL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Imposta il valore del campo TTL.\\ - \const{IP\_HDRINCL}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Passa l'intestazione di IP nei dati.\\ - \const{IP\_RECVERR}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Abilita la gestione degli errori.\\ - \const{IP\_MTU\_DISCOVER}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Imposta il Path MTU Discovery.\\ - \const{IP\_MTU}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Legge il valore attuale della 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$&$\bullet$&\texttt{int}& - Imposta il TTL per i pacchetti multicast.\\ - \const{IP\_MULTICAST\_LOOP}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Controlla il reinvio a se - stessi dei dati di multicast.\\ - \const{IP\_ADD\_MEMBERSHIP}& &$\bullet$&$\bullet$&\texttt{int}& - Si unisce a un gruppo di multicast.\\ + \const{IP\_OPTIONS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Imposta o riceve le opzioni di IP.\\ + \const{IP\_PKTINFO} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Passa un messaggio di informazione.\\ + \const{IP\_RECVTOS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Passa un messaggio col campo TOS.\\ + \const{IP\_RECVTTL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Passa un messaggio col campo TTL.\\ + \const{IP\_RECVOPTS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Passa un messaggio con le opzioni IP.\\ + \const{IP\_RETOPTS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Passa un messaggio con le opzioni IP non trattate.\\ + \const{IP\_TOS} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Imposta il valore del campo TOS.\\ + \const{IP\_TTL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Imposta il valore del campo TTL.\\ + \const{IP\_HDRINCL} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Passa l'intestazione di IP nei dati.\\ + \const{IP\_RECVERR} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Abilita la gestione degli errori.\\ + \const{IP\_MTU\_DISCOVER} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Imposta il Path MTU Discovery.\\ + \const{IP\_MTU} &$\bullet$& &$\bullet$&\texttt{int}& + Legge il valore attuale della 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$&$\bullet$&\texttt{int}& + Imposta il TTL per i pacchetti multicast.\\ + \const{IP\_MULTICAST\_LOOP} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Controlla il reinvio a se stessi dei dati di multicast.\\ + \const{IP\_ADD\_MEMBERSHIP} & &$\bullet$&$\bullet$&\texttt{int}& + Si unisce a un gruppo di multicast.\\ \const{IP\_DROP\_MEMBERSHIP}& &$\bullet$&$\bullet$&\texttt{int}& - Si sgancia da un gruppo di multicast.\\ - \const{IP\_MULTICAST\_IF}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Imposta l'interfaccia locale di un socket - multicast.\\ + Si sgancia da un gruppo di multicast.\\ + \const{IP\_MULTICAST\_IF} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Imposta l'interfaccia locale di un socket multicast.\\ \hline \end{tabular} \caption{Le opzioni disponibili al livello \const{SOL\_IP}.} \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{getsockopt} vengono lette le + opzioni IP utilizzate per la spedizione, quando la si usa con + \func{setsockopt} vengono impostate le opzioni specificate. L'uso di questa + opzione richiede una profonda conoscenza del funzionamento del protocollo, + torneremo in parte sull'argomento in sez.~\ref{sec:sock_advanced_xxx}. + + +\item[\const{IP\_PKTINFO}] Quando abilitata l'opzione permette di ricevere + insieme ai pacchetti un messaggio ancillare (vedi + sez.~\ref{sec:TCP_ancillary_data}) di tipo \const{IP\_PKTINFO} contenente + 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 + utilizzato (nel campo \var{ipi\_spec\_dst}) e l'indirizzo remoto dello + stesso (nel campo \var{ipi\_addr}). + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/pktinfo.h} + \end{minipage} + \caption{La struttura \structd{pktinfo} usata dall'opzione + \const{IP\_PKTINFO} per ricavare informazioni sui pacchetti di un socket + di tipo \const{SOCK\_DGRAM}.} + \label{fig:sock_pktinfo_struct} +\end{figure} + + +L'opzione è utilizzabile solo per socket di tipo \const{SOCK\_DGRAM}. Questa è +una opzione introdotta con i kernel della serie 2.2.x, ed è specifica di +Linux;\footnote{non dovrebbe pertanto essere utilizzata se si ha a cuore la + portabilità.} essa permette di sostituire le opzioni \const{IP\_RECVDSTADDR} +e \const{IP\_RECVIF} presenti in altri Unix (la relativa informazione è quella +ottenibile rispettivamente dai campi \var{ipi\_addr} e \var{ipi\_ifindex} di +\struct{pktinfo}). + + +\item[\const{IP\_RECVTOS}] Quando abilitata l'opzione permette di ricevere + insieme ai pacchetti un messaggio ancillare di tipo \const{IP\_TOS}, che + contiene un byte con il valore del campo \textit{Type of Service} + dell'intestazione IP del pacchetto stesso (vedi sez.~\ref{sec:IP_header}). + Prende per \param{optval} un intero usato come valore logico. + +\item[\const{IP\_RECVTTL}] Quando abilitata l'opzione permette di ricevere + insieme ai pacchetti un messaggio ancillare di tipo \const{IP\_RECVTTL}, + contenente un byte con il valore del campo \textit{Time to Live} + dell'intestazione IP (vedi sez.~\ref{sec:IP_header}). L'opzione richiede + per \param{optval} un intero usato come valore logico. L'opzione non è + supportata per socket di tipo \const{SOCK\_STREAM}. + +\item[\const{IP\_RECVOPTS}] Quando abilitata l'opzione permette di ricevere + insieme ai pacchetti un messaggio ancillare di tipo \const{IP\_OPTIONS}, + contenente le opzioni IP del protocollo (vedi sez.~\ref{sec:IP_options}). Le + intestazioni di instradamento e le altre opzioni sono già riempite con i + dati locali. L'opzione richiede per \param{optval} un intero usato come + valore logico. L'opzione non è supportata per socket di tipo + \const{SOCK\_STREAM}. + +\item[\const{IP\_RETOPTS}] Identica alla precedente \const{IP\_RECVOPTS}, ma + in questo caso restituisce i dati grezzi delle opzioni, senza che siano + riempiti i capi di instradamento e le marche temporali. L'opzione richiede + per \param{optval} un intero usato come valore logico. L'opzione non è + supportata per socket di tipo \const{SOCK\_STREAM}. + + +\item[\const{IP\_TOS}] L'opzione consente di leggere o impostare il campo + \textit{Type of Service} dell'intestazione IP (vedi + sez.~\ref{sec:IP_header}) che permette di indicare le priorità dei + pacchetti. Il campo TOS è di 8 bit e l'opzione richiede per \param{optval} + un intero che ne contiene il valore. Sono definite anche alcune costanti che + definiscono alcuni valori standardizzati per il \textit{Type of Service}, + riportate in tab.~\ref{tab:IP_TOS_values}, il valore di default usato da + Linux è \const{IPTOS\_LOWDELAY}, ma esso può essere modificato con le + funzionalità del cosiddetto \textit{Advanced Routing}. Si ricordi che la + priorità dei pacchetti può essere impostata anche in maniera indipendente + dal protocollo utilizzando l'opzione \const{SO\_PRIORITY} illustrata in + sez.~\ref{sec:sock_generic_options}. + + +\item[\const{IP\_TTL}] L'opzione consente di leggere o impostare il campo + \textit{Time to Live} dell'intestazione IP (vedi sez.~\ref{sec:IP_header}). + Il campo TTL è di 8 bit e l'opzione richiede che \param{optval} sia un + intero, che ne conterrà il valore. + + +\item[\const{IP\_HDRINCL}] Se abilitata l'utente deve fornire lui stesso + l'intestazione IP in cima ai propri dati. L'opzione è valida soltanto per + socket di tipo \const{SOCK\_RAW}, e quando utilizzata eventuali valori + impostati con \const{IP\_OPTIONS}, \const{IP\_TOS} o \const{IP\_TTL} sono + ignorati. In ogni caso prima della spedizione alcuni campi + dell'instestazione vengono comunque modificati dal kernel, torneremo + sull'argomento in sez.~\ref{sec:socket_raw_xxx} + + +\item[\const{IP\_RECVERR}] Questa è una opzione introdotta con i kernel della + serie 2.2.x, ed è specifica di Linux. Essa permette di usufruire di un + meccanismo affidabile per ottenere un maggior numero di informazioni in caso + di errori. Se l'opzione è abilitata tutti gli errori generati su un socket + vengono memorizzati su una coda, dalla quale poi possono essere letti con + \func{recvmsg} (torneremo su questo in sez.~\ref{sec:TCP_ancillary_data}). + L'opzione richiede per \param{optval} un intero usato come valore logico; + l'opzione non è applicabile a socket di tipo \const{SOCK\_STREAM}. + +\item[\const{IP\_MTU\_DISCOVER}] Questa è una opzione introdotta con i kernel + della serie 2.2.x, ed è specifica di Linux. L'opzione permette di scrivere + o leggere le impostazioni usate nella determinazione della \textit{Maximum + Tranfer Unit} (vedi sez.~\ref{sec:net_lim_dim}) per il socket. Il valore + di default è determinato dal parametro \texttt{ip\_no\_pmtu\_disc} di + \func{sysctl}. + +\item[\const{IP\_MTU}] Permette di leggere il valore della \textit{Maximum + Tranfer Unit} di percorso del socket. L'opzione richiede per + \param{optval} un intero che conterrà il valore della MTU in byte. Questa è + una opzione introdotta con i kernel della serie 2.2.x, ed è specifica di + Linux. + +\item[\const{IP\_ROUTER\_ALERT}] Questa è una opzione introdotta con i kernel + della serie 2.2.x, ed è specifica di Linux. + +\item[\const{IP\_MULTICAST\_TTL}] L'opzione permette di impostare o leggere il + valore del campo TTL per i pacchetti in uscita associati al socket. È + importante che questo valore sia il più basso possibile, ed il default è 1, + che significa che i pacchetti non potranno uscire dalla rete locale. Questa + opzione consente ai programmi che lo richiedono di superare questo limite. + L'opzione richiede per \param{optval} un intero che conterrà il valore del + 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 @@ -2729,8 +2867,40 @@ elenco: In generale se si vuole che eventuali client possano ricevere i dati che si inviano occorre che questa funzionalità sia abilitata (come avviene di default). Qualora però non si voglia generare traffico per dati che già sono - disponibili l'uso di questa opzione permette di disabilitare questo tipo di - traffico. + disponibili in locale l'uso di questa opzione permette di disabilitare + questo tipo di traffico. + +\item[\const{IP\_ADD\_MEMBERSHIP}] L'opzione consente di unirsi ad gruppo di + multicast, e può essere usata solo con \func{setsockopt}. L'argomento + \param{optval} in questo caso deve essere una struttura di tipo + \struct{ip\_mreqn}, illustrata in fig.~\ref{fig:ip_mreqn_struct}, che + permette di indicare, con il campo \var{imr\_multiaddr} l'indirizzo del + gruppo di multicast a cui ci si vuole unire, con il campo \var{imr\_address} + l'indirizzo dell'interfaccia locale con cui unirsi al gruppo di multicast e + con \var{imr\_ifindex} l'indice dell'interfaccia da utilizzare (un valore + nullo indica una interfaccia qualunque). + + Per compatibilità è possibile utilizzare anche un argomento di tipo + \struct{ip\_mreq}, una precedente versione di \struct{ip\_mreqn}, che + differisce da essa soltanto per l'assenza del campo \var{imr\_ifindex}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includestruct{listati/ip_mreqn.h} + \end{minipage} + \caption{La struttura \structd{ip\_mreqn} utilizzata dalle opzioni dei socket + per le operazioni concernenti l'appartenenza ai gruppi di multicast.} + \label{fig:ip_mreqn_struct} +\end{figure} + + + + +\item[\const{IP\_DROP\_MEMBERSHIP}] + +\item[\const{IP\_MULTICAST\_IF}] + \end{basedescript} @@ -2772,10 +2942,11 @@ specifico quando la si impiega su file descriptor associati a dei socket. Come ultimo argomento di questa sezione tratteremo l'uso della funzione \func{sysctl} (che è stata introdotta nelle sue funzionalità generiche in sez.~\ref{sec:sys_sysctl}) per quanto riguarda le sue capacità di effettuare -impostazioni relative a proprietà generali dei socket (di tutti quelli di un -certo tipo o di tutti quelli che usano un certo protocollo) rispetto alle -funzioni viste finora che consentono di controllare quelle di un singolo -socket. +impostazioni relative alle proprietà dei socket. La differenza nell'uso di +\func{sysctl} rispetto alle funzioni viste finora è che esse consentono di +controllare le proprietà di un singolo socket, mentre con \func{sysctl} si +impostano proprietà (o valori di default) validi a livello dell'intero +sistema. Le opzioni disponibili per le proprietà della rete sono riportate nella gerarchia dei valori impostabili con \func{sysctl}, sotto il nodo @@ -2783,7 +2954,8 @@ gerarchia dei valori impostabili con \func{sysctl}, sotto il nodo \texttt{/proc}, sotto \texttt{/proc/sys/net}. In genere sotto questa directory compaiono le sottodirectory (corrispondenti ad altrettanti sottonodi per \func{sysctl}) relative ai vari protocolli e tipi di interfacce su cui è -possibile intervenire; un contenuto tipico è il seguente: +possibile intervenire per effettuare impostazioni; un contenuto tipico di +questa directory è il seguente: \begin{verbatim} /proc/sys/net/ |-- core @@ -2794,11 +2966,13 @@ possibile intervenire; un contenuto tipico |-- token-ring `-- unix \end{verbatim} +e sono presenti varie centinaia di diversi parametri; nel nostro caso ci +limiteremo a vedere quelli più significativi. - -Nella directory \texttt{/proc/sys/net/core} sono disponibili le opzioni -generiche dei socket, descritte anche nella rispettiva pagina di -manuale.\footnote{quella accessibile con \texttt{man 7 socket}.} Queste sono: +Nella directory \texttt{/proc/sys/net/core} sono disponibili i parametri +generici validi per tutti i socket, quelli descritti anche nella rispettiva +pagina di manuale.\footnote{quella accessibile con \texttt{man 7 socket}.} +I principali sono: \begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}} \item[\texttt{rmem\_default}] imposta la dimensione di default del buffer di @@ -2817,6 +2991,17 @@ manuale.\footnote{quella accessibile con \texttt{man 7 socket}.} Queste sono: \item[\texttt{optmem\_max}] \end{basedescript} +Nella directory \texttt{/proc/sys/net/ipv4} sono disponibili i parametri per i +socket IPv4, descritti anche nella rispettiva pagina di +manuale.\footnote{quella accessibile con \texttt{man 7 ip}.} I principali +sono: +\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}} +\item[\texttt{ip\_no\_pmtu\_disc}] imposta la discliplina di ricerca della + \textit{Path MTU} (vedi sez.~\ref{sec:net_lim_dim} e + sez.~\ref{sec:sock_ipv4_options}). +\end{basedescript} + + %%% Local Variables: %%% mode: latex