Aggiunta gethostbyaddr e corretti dei riferimenti alle strutture per gli
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 5 Sep 2004 16:17:46 +0000 (16:17 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 5 Sep 2004 16:17:46 +0000 (16:17 +0000)
indirizzi IP

listati/sockaddr_in6.h
sockctrl.tex
socket.tex

index 34bc216..f6fe615 100644 (file)
@@ -1,5 +1,5 @@
 struct sockaddr_in6 {
-    uint16_t        sin6_family;   /* AF_INET6 */
+    sa_family_t     sin6_family;   /* AF_INET6 */
     in_port_t       sin6_port;     /* port number */
     uint32_t        sin6_flowinfo; /* IPv6 flow information */
     struct in6_addr sin6_addr;     /* IPv6 address */
index 1dbc855..3adaa2b 100644 (file)
@@ -678,7 +678,9 @@ IPv4, se si vogliono ottenere degli indirizzi IPv6 occorrer
 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 resolver; dato che questo non è molto comodo è stata
-definita un'altra funzione, \funcd{gethostbyname2}, il cui prototipo è:
+definita\footnote{questa è una estensione fornita dalle \acr{glibc},
+  disponibile anche in altri sistemi unix-like.} un'altra funzione,
+\funcd{gethostbyname2}, il cui prototipo è:
 \begin{functions}
   \headdecl{netdb.h} 
   \headdecl{sys/socket.h}
@@ -762,10 +764,24 @@ ci sono precauzioni particolari da prendere.\footnote{volendo essere pignoli
   avuto un errore con \func{gethostbyname}, ma si ricordi che la sicurezza non
   è mai troppa.}
 
-Le funzioni illustrate finora hanno un difetto fondamentale, utilizzando una
-area di memoria interna per allocare il contenuto della struttura
-\struct{hostent} non possono essere rientranti. Per questo motivo ne sono
-state definite delle versioni alternative rientranti, al solito queste sono
+Le funzioni illustrate finora hanno un difetto: utilizzando una area di
+memoria interna per allocare i contenuti della struttura \struct{hostent} non
+possono essere rientranti. Questo comporta anche che in due successive
+chiamate i dati potranno essere sovrascritti. Si tenga presente poi che
+copiare il contenuto della sola struttura non è sufficiente per salvare tutti
+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
+  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.}
+
+Per ovviare a questi problemi nelle \acr{glibc} sono definite anche delle
+versioni rientranti delle precedenti funzioni, al solito queste sono
 caratterizzate dall'avere un suffisso \texttt{\_r}, pertanto avremo le due
 funzioni \funcd{gethostbyname\_r} e \funcd{gethostbyname2\_r} i cui prototipi
 sono:
@@ -785,16 +801,16 @@ sono:
     negativo in caso di errore.}
 \end{functions}
 
-Gli argomenti \param{name} (e \param{af} per \func{gethostbyname2}) hanno lo
-stesso significato visto in precedenza. Tutti gli altri argomenti hanno lo
+Gli argomenti \param{name} (e \param{af} per \func{gethostbyname2\_r}) hanno
+lo stesso significato visto in precedenza. Tutti gli altri argomenti hanno lo
 stesso significato per entrambe le funzioni. Per evitare l'uso di variabili
 globali si dovrà allocare preventivamente una struttura \struct{hostent} in
 cui ricevere il risultato, passandone l'indirizzo alla funzione nell'argomento
-\param{ret}.  Inoltre, dato che \struct{hostent} contiene solo dei puntatori,
-dovrà essere allocato anche un buffer in cui le funzioni possano scrivere
-tutti i dati del risultato dell'interrogazione, l'indirizzo e la lunghezza di
-questo buffer devono essere indicati con gli argomenti \param{buf} e
-\param{buflen}. 
+\param{ret}.  Inoltre, dato che \struct{hostent} contiene dei puntatori, dovrà
+essere allocato anche un buffer in cui le funzioni possano scrivere tutti i
+dati del risultato dell'interrogazione da questi puntati; l'indirizzo e la
+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
@@ -816,9 +832,10 @@ con un buffer di dimensione maggiore.
 Una delle caratteristiche delle interrogazioni al servizio DNS è che queste
 sono normalmente eseguite con il protocollo UDP, ci sono casi in cui si
 preferisce che vengano usate connessioni permanenti con il protocollo TCP. Per
-ottenere questo sono previste delle funzioni apposite (oltre che delle opzioni
-in \var{\_\_res.options}); la prima è \funcd{sethostent}, il cui prototipo
-è:
+ottenere\footnote{si potrebbero impostare direttamente le opzioni di
+  \var{\_\_res.options}, ma queste funzioni permettono di semplificare la
+  procedura.} questo sono previste delle funzioni apposite; la prima è
+\funcd{sethostent}, il cui prototipo è:
 \begin{prototype}{netdb.h}
 {void sethostent(int stayopen)}
 
@@ -827,6 +844,58 @@ Richiede l'uso di connessioni per le interrogazioni ad un server DNS.
 \bodydesc{La funzione non restituisce nulla.}
 \end{prototype}
 
+La funzione permette di richiedere l'uso di connessioni TCP per la richiesta
+dei dati, e che queste restino aperte per successive richieste. Il valore
+dell'argomento \param{stayopen} indica se attivare questa funzionalità, un
+valore pari a 1 (o diverso da zero), che indica una condizione vera in C,
+attiva la funzionalità.  Come si attiva l'uso delle connessioni TCP lo si può
+disattivare con la funzione \funcd{endhostent}; il suo prototipo è:
+\begin{prototype}{netdb.h}
+{void endhostent(void)}
+
+Disattiva l'uso di connessioni per le interrogazioni ad un server DNS.
+
+\bodydesc{La funzione non restituisce nulla.}
+\end{prototype}
+\noindent e come si può vedere la funzione è estremamente semplice, non
+richiedendo nessun argomento.
+
+
+Infine si può richiedere la risoluzione inversa di un indirizzo IP od IPv6,
+per ottenerne il nome a dominio ad esso associato, per fare questo si può
+usare la funzione \funcd{gethostbyaddr}, il cui prototipo è:
+\begin{functions}
+  \headdecl{netdb.h} 
+  \headdecl{sys/socket.h} 
+  \funcdecl{struct hostent *gethostbyaddr(const char *addr, int len, int
+    type)}
+
+  Richiede la risoluzione inversa di un indirizzo IP.
+       
+  \bodydesc{La funzione restituisce l'indirizzo ad una struttura
+    \struct{hostent} in caso di successo ed \const{NULL} in caso di errore.}
+\end{functions}
+
+In questo caso l'argomento \param{addr} dovrà essere il puntatore ad una
+appropriata struttura contentente il valore dell'indirizzo IP (o IPv6) che si
+vuole risolvere. L'uso del tipo \type{char *} per questo argomento ha è
+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, 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 si successo, un puntatore ad una struttura
+\struct{hostent}, solo che la ricerca è fatta richiedendo al DNS un record di
+tipo \texttt{PTR}. In caso di errore al solito viene usata la variabile
+\var{h\_errno} per restituire un opportuno codice. In questo caso il valore
+dei vari campi \var{h\_addr\_list} viene inizializzato al valore passa
 
 
 \subsection{Altre funzioni di gestione dei nomi}
index 4b450aa..968a18c 100644 (file)
@@ -466,7 +466,7 @@ come struttura (un resto di una implementazione precedente in cui questa era
 una \direct{union} usata per accedere alle diverse classi di indirizzi) che
 direttamente come intero. In \file{netinet/in.h} vengono definite anche alcune
 costanti che identificano alcuni indirizzi speciali, riportati in
-tab.~\ref{tab:TCP_ipv4_addr}.
+tab.~\ref{tab:TCP_ipv4_addr}, che reincontreremo più avanti.
 
 Infine occorre sottolineare che sia gli indirizzi che i numeri di porta devono
 essere specificati in quello che viene chiamato \textit{network order}, cioè
@@ -500,17 +500,17 @@ il campo \var{sin6\_port} 
 il campo \var{sin6\_flowinfo} è a sua volta diviso in tre parti di cui i 24
 bit inferiori indicano l'etichetta di flusso, i successivi 4 bit la priorità e
 gli ultimi 4 sono riservati. Questi valori fanno riferimento ad alcuni campi
-specifici dell'header dei pacchetti IPv6 (vedi sez.~\ref{sec:IP_ipv6head}) ed il
-loro uso è sperimentale.
-
-Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6, infine
-il campo \var{sin6\_scope\_id} è un campo introdotto in Linux con il kernel
-2.4, per gestire alcune operazioni riguardanti il multicasting.
-Si noti che questa struttura ha una dimensione maggiore della struttura
-\struct{sockaddr} generica vista in fig.~\ref{fig:sock_sa_gen_struct}, quindi
-occorre stare attenti a non avere fatto assunzioni riguardo alla possibilità
-di contenere i dati nelle dimensioni di quest'ultima.
+specifici dell'header dei pacchetti IPv6 (vedi sez.~\ref{sec:IP_ipv6head}) ed
+il loro uso è sperimentale.
+
+Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
+espresso da un vettore di 16 byte. Infine il campo \var{sin6\_scope\_id} è un
+campo introdotto in Linux con il kernel 2.4, per gestire alcune operazioni
+riguardanti il multicasting.  Si noti infine che \struct{sockaddr\_in6} ha una
+dimensione maggiore della struttura \struct{sockaddr} generica di
+fig.~\ref{fig:sock_sa_gen_struct}, quindi occorre stare attenti a non avere
+fatto assunzioni riguardo alla possibilità di contenere i dati nelle
+dimensioni di quest'ultima.
 
 
 \subsection{La struttura degli indirizzi locali}