X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sockctrl.tex;h=1dbc855c05b9fcaec8eff896c96c3ff141e139a1;hp=5efe128ba47c01c7c95b5ad630c5c2993f2d4de5;hb=b120ef0b0570efae73c8e50576a3f98fb7830769;hpb=062e1036f07efd623e11b5bb194bcf2684dd7866 diff --git a/sockctrl.tex b/sockctrl.tex index 5efe128..1dbc855 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -37,10 +37,14 @@ propriet 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}. In realtà per DNS si intendono spesso i server che forniscono su -internet questo servizio, mentre nel nostro caso affronteremo la problematica -dal lato client, di un qualunque programma che necessita di compiere questa -operazione. + 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 + 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 +affronteremo la problematica dal lato client, di un qualunque programma che +necessita di compiere questa operazione. \begin{figure}[htb] \centering @@ -66,42 +70,67 @@ necessarie a fornire la risposta, che possono essere la lettura delle informazioni mantenute nei relativi dei file statici presenti sulla macchina, una interrogazione ad un DNS (che a sua volta, per il funzionamento del protocollo può interrogarene altri) o la richiesta ad altri server per i quali -sia fornito il supporto, come LDAP. - -La configurazione del resolver attiene più alla amministrazione di sistema che -alla programmazione, ciò non di meno, prima di trattare le varie funzioni che -vale la pena farne una panoramica. Originariamente la configurazione +sia fornito il supporto, come LDAP.\footnote{la sigla LDAP fa riferimento ad + un protocollo, il \textit{Lightweight Directory Access Protocol}, che + prevede un meccanismo per la gestione di \textsl{elenchi} di informazioni + via rete; il contenuto di un elenco può essere assolutamente generico, e + questo permette il manenimento dei più vari tipi di informazioni su una + infrastruttura di questo tipo.} + +La configurazione del \textit{resolver} attiene più alla amministrazione di +sistema che alla programmazione, ciò non di meno, prima di trattare le varie +funzioni di librerie utilizzate dai programmi, vale la pena fare una +panoramica generale. Originariamente la configurazione del \textit{resolver} riguardava esclusivamente le questioni relative alla gestione dei nomi a dominio, e prevedeva solo l'utilizzo del DNS e del file statico -\file{/etc/hosts}. +\file{/etc/hosts}. -In questo caso il file di configurazione principale è \file{/etc/resolv.conf} -che contiene in sostanza l'elenco dei server DNS da contattare, a cui si -affianca il file \file{/etc/host.conf} il cui scopo principale è indicare -l'ordine in cui eseguire la risoluzione dei nomi (se usare prima i valori di -\file{/etc/hosts} o il DNS); tralasciamo i dettagli relativi alle varie -direttive che possono essere usate in questi file, che si trovano nelle -relative pagine di manuale. +Per questo aspetto il file di configurazione principale del sistema è +\file{/etc/resolv.conf} che contiene in sostanza l'elenco degli indirizzi IP +dei server DNS da contattare; a questo si affianca il file +\file{/etc/host.conf} il cui scopo principale è indicare l'ordine in cui +eseguire la risoluzione dei nomi (se usare prima i valori di \file{/etc/hosts} +o quelli del DNS). Tralasciamo i dettagli relativi alle varie direttive che +possono essere usate in questi file, che si trovano nelle rispettive pagine di +manuale. Con il tempo però è divenuto possibile fornire diversi sostituti per l'utilizzo delle associazione statiche in \file{/etc/hosts}, inoltre oltre alla risoluzione dei nomi a dominio ci sono anche altri nomi da risolvere, come quelli che possono essere associati ad una rete (invece che ad una -singola macchina) o ai gruppi di macchine definiti dal servizio NIS, o come -quelli dei protocolli e dei servizi che sono mantenuti nei file statici -\file{/etc/protocols} e \file{/etc/services}. Tutte queste sono informazioni -che normalmente non si trovano su un DNS, ma che in un ambiente distribuito -possono essere centralizzate su opportuni server (ad esempio su LDAP) in grado -di mantenerle. - - - -Il sistema del \textit{Name Service Switch} (cui faremo riferimento in seguito -con l'acronimo NSS) è un sistema di librerie dinamiche che permette di -definire in maniera generica sia i supporti su cui mantenere i dati di -corrispondenza fra nomi e valori numerici, sia l'ordine in cui effettuare le -ricerche sui vari supporti disponibili. Il sistema prevede una serie di -possibili classi di corrispondenza, riportate in +singola macchina) o ai gruppi di macchine definiti dal servizio +NIS,\footnote{il \textit{Network Information Service} è un servizio, creato da + Sun, e poi diffuso su tutte le piattaforme unix-like, che permette di + raggruppare all'interno di una rete (in quelli che appunto vengono chiamati + \textit{netgroup}) varie macchine, centralizzando i servizi di definizione + di utenti e gruppi e di autenticazione, oggi è sempre più spesso sostituito + da LDAP.} o come quelli dei protocolli e dei servizi che sono mantenuti nei +file statici \file{/etc/protocols} e \file{/etc/services}. Molte di queste +informazioni non si trovano su un DNS, ma in una rete locale può essere molto +utile centralizzare il mentenimento di alcune di esse su opportuni server. +Inoltre l'uso di diversi supporti possibili per le stesse informazioni (ad +esempio il nome delle macchine può essere mantenuto sia tramite +\file{/etc/hosts}, che con il DNS, che con NIS) comporta il problema +dell'ordine in cui questi vengono interrogati.\footnote{con le implementazioni + classiche i vari supporti erano introdotti modificando direttamente le + funzioni di liberia, prevedendo un ordine di interrogazione predefinito e + non modificabile (a meno di una ricompilazione delle librerie stesse).} + +Per risolvere questa serie di problemi la risoluzione dei nomi a dominio +eseguira dal \textit{resolver} è stata inclusa all'interno di un meccanismo +generico per la risoluzione di corripondenze fra nomi ed informazioni ad essi +associate chiamato \textit{Name Service Switch}\footnote{il sistema è stato + introdotto la prima volta nelle librerie standard di Solaris, le \acr{glibc} + hanno ripreso lo stesso schema, si tenga presente che questo sistema non + esiste per altre librerie standard come le \acr{libc5} o le \acr{uclib}.} +cui abbiamo accennato anche in sez.~\ref{sec:sys_user_group} per quanto +riguarda la gestione dei dati associati a utenti e gruppi. Il \textit{Name + Service Switch} (cui spesso si fa riferimento con l'acronimo NSS) è un +sistema di librerie dinamiche che permette di definire in maniera generica sia +i supporti su cui mantenere i dati di corrispondenza fra nomi e valori +numerici, sia l'ordine in cui effettuare le ricerche sui vari supporti +disponibili. Il sistema prevede una serie di possibili classi di +corrispondenza, quelle attualmente definite sono riportate in tab.~\ref{tab:sys_NSS_classes}. \begin{table}[htb] @@ -137,73 +166,473 @@ tab.~\ref{tab:sys_NSS_classes}. \label{tab:sys_NSS_classes} \end{table} - - -Questo ha portato alla creazione di un sistema di risoluzione più ampio, il -\textit{Name Service Switch} di cui il \textit{resolver} viene a costituire un -sottoinsieme. Questo sistema permette di definire in maniera generica -(attraverso una serie di librerie dinamiche) sia i supporti su cui mantenere i -dati di corrispondenza fra nomi e valori numerici, sia l'ordine in cui -effettuare le ricerche sui vari supporti disponibili. Il sistema è -controllato dal file \file{/etc/nsswitch.conf}, ed anche per questo si può -fare riferimento alle pagine di manuale ed al relativo capitolo nel manuale -\cite{glibc} delle \textsl{glibc}. - -Il -sistema è controllato dal file \file{/etc/nsswitch.conf}, ed anche per questo -si può fare riferimento alle pagine di manuale ed al relativo capitolo nel -manuale \cite{glibc} delle \textsl{glibc}. - - - -Per questo motivo anche il sistema del \textit{resolver} è stato poi incluso -all'interno del sistema sistema di risoluzione più ampio costituito dal -\textit{Name Service Switch} che abbiamo visto in -sez.~\ref{sec:sys_user_group}, dove sono previste le funzionalità di controllo -per la risoluzione anche di questo tipo di corrispondenze. Questo significa -allora, per quanto riguarda la risoluzione dei nomi a dominio, che oltre ai -file che abbiamo appena illustrato, dovremo tenere in considerazione anche il -contenuto del file \file{/etc/nsswitch.conf}. +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 + considerato un commento.} di configurazione per ciascuna di queste classi, +che viene inizia col nome di tab.~\ref{tab:sys_NSS_classes} seguito da un +carattere ``\texttt{:}'' e prosegue con la lista dei \textsl{servizi} su cui +le relative informazioni sono raggiungibili, scritti nell'ordine in cui si +vuole siano interrogati. + +Ogni servizio è specificato a sua volta da un nome, come \texttt{file}, +\texttt{dns}, \texttt{db}, ecc. che identifica la libreria dinamica che +realizza l'interfaccia con esso. Per ciascun servizio se \texttt{NAME} è il +nome utilizzato dentro \file{/etc/nsswitch.conf}, dovrà essere presente +(usualmente in \file{/lib}) una libreria \texttt{libnss\_NAME} che ne +implementa le funzioni. In ogni caso, qualunque sia la modalità con cui ricevono i dati o il supporto su cui vengono mantenuti, e che si usino o meno funzionalità aggiuntive fornire dal sistema del \textit{Name Service Switch}, dal punto di vista di un -programma che deve effettuare la risoluzione di un nome, tutto quello che -conta sono le funzioni che il \textit{resolver} mette a +programma che deve effettuare la risoluzione di un nome a dominio, tutto +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. +\subsection{Le funzioni di interrogazione del \textit{resolver}} +\label{sec:sock_resolver_functions} + +Prima di trattare le funzioni usate normalmente nella risoluzione dei nomi a +dominio conviene trattare in maniera più dettagliata il meccanismo principale +da esse utilizzato e cioè quello del servizio DNS. Come accennato questo, +benché in teoria sia solo uno dei possibili supporti su cui mantenere le +informazioni, in pratica costituisce il meccanismo principale con cui vengono +risolti i nomi a dominio. Per questo motivo esistono una serie di funzioni di +libreria che servono specificamente ad esseguire delle interrogazioni verso un +server DNS, funzioni che poi vengono utilizzate per realizzare le funzioni +generiche di libreria usate anche dal sistema del \textit{resolver}. + +Il sistema del DNS è in sostanza di un database distribuito organizzato in +maniera gerarchica, i dati vengono mantenuti in tanti server distinti ciascuno +dei quali si occupa della risoluzione del proprio \textsl{dominio}; i nomi a +dominio sono organizzati in una struttura ad albero analoga a quella +dell'albero dei file, con domini di primo livello (come i \texttt{.org}), +secondo livello (come \texttt{.truelite.it}), ecc. In questo caso le +separazioni sono fra i vari livelli sono definite dal carattere ``\texttt{.}'' +ed i nomi devono essere risolti da destra verso sinistra.\footnote{per chi si + stia chiedendo quale sia la radice di questo albero, cioè l'equivalente di + ``\texttt{/}'', la risposta è il dominio speciale ``\texttt{.}'', che in + genere non viene mai scritto esplicitamente, ma che, come chiunque abbia + configurato un server DNS sa bene, esiste ed è gestito dai cosiddetti + \textit{root DNS} che risolvono i domini di primo livello.} Il meccanismo +funziona con il criterio della \textsl{delegazione}, un server responsabile +per un dominio di primo livello può delegare la risoluzione degli indirizzi +per un suo dominio di secondo livello ad un altro server, il quale a sua volta +potrà delegare la risoluzione di un eventuale sottodominio di terzo livello ad +un altro server ancora. + +In realtà un server DNS è in grado di fare altro rispetto alla risoluzione di +un nome a dominio in un indirizzo IP; ciascuna voce nel database viene +chiamata \textit{resource record}, e può contenere diverse informazioni. In +genere i \textit{resource record} vengono classificati per la \textsl{classe + di indirizzi} cui i dati contenuti fanno riferimento, e per il \textsl{tipo} +di questi ultimi.\footnote{ritroveremo classi di indirizzi e tipi di record + più avanti in tab.~\ref{tab:DNS_address_class} e + tab.~\ref{tab:DNS_record_type}.} Oggigiorno i dati mantenuti nei server DNS +sono quasi esclusivamente relativi ad indirizzi internet, per cui in pratica +viene utilizzata soltanto una classe di indirizzi; invece le corrispondenze +fra un nome a dominio ed un indirizzo IP sono solo uno fra i vari tipi di +informazione che un server DNS fornisce normalmente. + +L'esistenza di vari tipi di informazioni è un'altro dei motivi per cui il +\textit{resolver} prevede, rispetto a quelle relative alla semplice +risoluzione dei nomi, un insieme di funzioni specifiche dedicate +all'interrogazione di un server DNS; la prima di queste funzioni è +\funcd{res\_init}, il cui prototipo è: +\begin{functions} + \headdecl{netinet/in.h} \headdecl{arpa/nameser.h} \headdecl{resolv.h} + \funcdecl{int res\_init(void)} + +Inizializza il sistema del \textit{resolver}. + +\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore.} +\end{functions} + +La funzione legge il contenuto dei file di configurazione (i già citati +\file{resolv.conf} e \file{host.conf}) per impostare il dominio di default, +gli indirizzi dei server DNS da contattare e l'ordine delle ricerche; se non +sono specificati server verrà utilizzato l'indirizzo locale, e se non è +definito un dominio di default sarà usato quello associato con l'indirizzo +locale (ma questo può essere sovrascritto con l'uso della variabile di +ambiente \texttt{LOCALDOMAIN}). In genere non è necessario eseguire questa +funzione direttamente in quanto viene automaticamente chiamata la prima volta +che si esegue una delle altre. + +Le impostazioni e lo stato del \textit{resolver} vengono mantenuti in una +serie di variabili raggruppate nei campi di una apposita struttura \var{\_res} +usata da tutte queste funzioni. Essa viene definita in \file{resolv.h} ed è +utilizzata internamente alle funzioni essendo definita come variabile globale; +questo consente anche di accedervi direttamente all'interno di un qualunque +programma, una volta che la sia opportunamente dichiarata come: +\includecodesnip{listati/resolv_option.c} + +Tutti i campi della struttura sono ad uso interno, e vengono usualmente +inizializzati da \func{res\_init} in base al contenuto dei file di +configurazione e ad una serie di valori di default. L'unico campo che può +essere utile modificare è \var{\_res.options}, una maschera binaria che +contiene una serie di bit di opzione che permettono di controllare il +comportamento del \textit{resolver}. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Costante} & \textbf{Significato} \\ + \hline + \hline + \const{RES\_INIT} & viene attivato se è stata chiamata + \func{res\_init}. \\ + \const{RES\_DEBUG} & stampa dei messaggi di debug.\\ + \const{RES\_AAONLY} & accetta solo risposte autoritative.\\ + \const{RES\_USEVC} & usa connessioni TCP per contattare i server + invece che l'usuale UDP.\\ + \const{RES\_PRIMARY} & interroga soltanto server DNS primari. + \\ + \const{RES\_IGNTC} & ignora gli errori di troncamento, non ritenta la + richiesta con una connessione TCP.\\ + \const{RES\_RECURSE} & imposta il bit che indica che si desidera + eseguire una interrogazione ricorsiva.\\ + \const{RES\_DEFNAMES} & se attivo \func{res\_search} aggiunge il nome + del dominio di default ai nomi singoli (che non + contengono cioè un ``\texttt{.}'').\\ + \const{RES\_STAYOPEN} & usato con \const{RES\_USEVC} per mantenere + aperte le connesioni TCP fra interrogazioni + diverse. \\ + \const{RES\_DNSRCH} & se attivo \func{res\_search} esegue le ricerche + di nomi di macchine nel dominio corrente o nei + domini ad esso sovrastanti.\\ + \const{RES\_INSECURE1} & blocca i controlli di sicurezza di tipo 1.\\ + \const{RES\_INSECURE2} & blocca i controlli di sicurezza di tipo 2.\\ + \const{RES\_NOALIASES} & blocca l'uso della variabile di ambiente + \texttt{HOSTALIASES}.\\ + \const{RES\_USE\_INET6} & restituisce indirizzi IPv6 con + \func{gethostbyname}. \\ + \const{RES\_ROTATE} & ruota la lista dei server DNS dopo ogni + interrogazione.\\ + \const{RES\_NOCHECKNAME}& non controlla i nomi per verificarne la + correttezza sintattica. \\ + \const{RES\_KEEPTSIG} & non elimina i record di tipo \texttt{TSIG}.\\ + \const{RES\_BLAST} & \\ + \const{RES\_DEFAULT} & è l'insieme di \const{RES\_RECURSE}, + \const{RES\_DEFNAMES} e \const{RES\_DNSRCH}.\\ + \hline + \end{tabular} + \caption{Costanti utilizzabili come valori per \var{\_res.options}.} + \label{tab:resolver_option} +\end{table} + +Per utilizzare questa funzionalità per modificare le impostazioni direttamente +da programma occorrerà impostare un opportuno valore per questo campo ed +invocare esplicitamente \func{res\_init}, dopo di che le altre funzioni +prenderanno le nuove impostazioni. Le costanti che definiscono i vari bit di +questo campo, ed il relativo significato sono illustrate in +tab.~\ref{tab:resolver_option}; trattandosi di una maschera binaria un valore +deve essere espresso con un opportuno OR aritmetico di dette costanti; ad +esempio il valore di default delle opzioni, epsresso dalla costante +\const{RES\_DEFAULT}, è definito come: +\includecodesnip{listati/resolv_option_def.c} + +Non tratteremo il significato degli altri campi non essendovi necessità di +modificarli direttamente; gran parte di essi sono infatti impostati dal +contenuto dei file di configurazione, mentre le funzionalità controllate da +alcuni di esse possono essere modificate con l'uso delle opportune variabili +di ambiente come abbiamo visto per \texttt{LOCALDOMAIN}. In particolare con +\texttt{RES\_RETRY} si soprassiede il valore del campo \var{retry} che +controlla quante volte viene ripetuto il tentativo di connettersi ad un server +DNS prima di dichiarare fallimento; il valore di default è 4, un valore nullo +significa bloccare l'uso del DNS. Infine con \texttt{RES\_TIMEOUT} si +soprassiede il valore del campo \var{retrans},\footnote{preimpostato al valore + della omonima costante \const{RES\_TIMEOUT} di \file{resolv.h}.} che è il +valore preso come base (in numero di secondi) per definire la scadenza di una +richiesta, ciascun tentativo di richiesta fallito viene ripetuto raddoppianto +il tempo di scadenza per il numero massimo di volte stabilito da +\texttt{RES\_RETRY}. + +La funzione di interrogazione principale è \funcd{res\_query}, che serve ad +eseguire una richiesta ad un server DNS per un nome a dominio +\textsl{completamente specificato} (quello che si chiama FQDN, \textit{Fully + Qualified Domain Name}); il suo prototipo è: + +\begin{functions} +\headdecl{netinet/in.h} +\headdecl{arpa/nameser.h} +\headdecl{resolv.h} +\funcdecl{int res\_query(const char *dname, int class, int type, + unsigned char *answer, int anslen)} + + Esegue una interrogazione al DNS. + +\bodydesc{La funzione restituisce un valore positivo pari alla lunghezza dei + dati scritti nel buffer \param{answer} in caso di successo e -1 in caso di + errore.} +\end{functions} + +La funzione esegue una interrogazione ad un server DNS relativa al nome da +risolvere passato nella stringa indirizzata da \param{dname}, inoltre deve +essere specificata la classe di indirizzi in cui eseguire la ricerca con +\param{class}, ed il tipo di \textit{resource record} che si vuole ottenere +con \param{type}. Il risultato della ricerca verrà scritto nel buffer di +lunghezza \param{anslen} puntato da \param{answer} che si sarà opportunamente +allocato in precedenza. + + +Una seconda funzione di ricerca, analoga a \func{res\_query}, che prende gli +stessi argomenti, ma che esegue l'interrogazione con le funzionalità +addizionali previste dalle due opzioni \const{RES\_DEFNAMES} e +\const{RES\_DNSRCH}, è \funcd{res\_search}, il cui prototipo è: +\begin{functions} +\headdecl{netinet/in.h} +\headdecl{arpa/nameser.h} +\headdecl{resolv.h} +\funcdecl{int res\_search(const char *dname, int class, int type, + unsigned char *answer, int anslen)} + + Esegue una interrogazione al DNS. + + \bodydesc{La funzione restituisce un valore positivo pari alla lunghezza dei + dati scritti nel buffer \param{answer} in caso di successo e -1 in caso di + errore.} +\end{functions} + +In sostanza la funzione ripete una serie di chiamate a \func{res\_query} +aggiungendo al nome contenuto nella stringa \param{dname} il dominio di +default da cercare, fermandosi non appena trova un risultato. Il risultato di +entrambe le funzioni viene scritto nel formato opportuno (che sarà diverso a +seconda del tipo di record richiesto) nel buffer di ritorno; sarà compito del +programma (o di altre funzioni) estrarre i relativi dati, esistono una serie +di funzioni interne usate per la scansione di questi dati, per chi fosse +interessato una trattazione dettagliata è riportata nel quattordicesimo +capitolo di \cite{DNSbind}. + +Le classi di indirizzi supportate da un server DNS sono tre, ma di queste in +pratica oggi viene utilizzata soltanto quella degli indirizzi internet; le +costanti che identificano dette classi, da usare come valore per l'argomento +\param{class} delle precedenti funzioni, sono riportate in +tab.~\ref{tab:DNS_address_class}.\footnote{esisteva in realtà anche una classe + \const{C\_CSNET} per la omonima rete, ma è stata dichiarata obsoleta.} + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Costante} & \textbf{Significato} \\ + \hline + \hline + \const{C\_IN} & indirizzi internet, in pratica i soli utilizzati oggi.\\ + \const{C\_HS} & indirizzi \textit{Hesiod}, utilizzati solo al MIT, oggi + completamente estinti. \\ + \const{C\_CHAOS}& indizzi per la rete \textit{Chaosnet}, un'altra rete + sperimentale nata al MIT. \\ + \const{C\_ANY} & indica un indirizzo di classe qualunque.\\ + \hline + \end{tabular} + \caption{Costanti identificative delle classi di indirizzi per l'argomento + \param{class} di \func{res\_query}.} + \label{tab:DNS_address_class} +\end{table} + +Come accennato le tipologie di dati che sono mantenibili su un server DNS sono +diverse, ed a ciascuna di essa corriponde un diverso tipo di \textit{resource + record}. L'elenco delle costanti\footnote{ripreso dai file di dichiarazione + \file{arpa/nameser.h} e \file{arpa/nameser\_compat.h}.} che definiscono i +valori che si possono usare per l'argomento \param{type} per specificare il +tipo di \textit{resource record} da richiedere è riportato in +tab.~\ref{tab:DNS_record_type}; le costanti (tolto il \texttt{T\_} iniziale) +hanno gli stessi nomi usati per identificare i record nei file di zona di +BIND,\footnote{BIND, acronimo di \textit{Berkley Internet Name Domain}, è una + implementazione di un server DNS, ed, essendo utilizzata nella stragrande + maggioranza dei casi, fa da rifererimento; i dati relativi ad un certo + dominio (cioè i suoi \textit{resource record} vengono mantenuti in quelli + che sono usualmente chiamati \textsl{file di zona}, e in essi ciascun tipo + di dominio è identificato da un nome che è appunto identico a quello delle + costanti di tab.~\ref{tab:DNS_record_type} senza il \texttt{T\_} iniziale.} +e che normalmente sono anche usati come nomi per indicare i record. + +\begin{table}[!htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Costante} & \textbf{Significato} \\ + \hline + \hline + \const{T\_A} & indirizzo di una stazione.\\ + \const{T\_NS} & server DNS autoritativo per il dominio richiesto.\\ + \const{T\_MD} & destinazione per la posta elettronica.\\ + \const{T\_MF} & redistributore per la posta elettronica.\\ + \const{T\_CNAME} & nome canonico.\\ + \const{T\_SOA} & inzio di una zona di autorità.\\ + \const{T\_MB} & nome a dominio di una casella di posta.\\ + \const{T\_MG} & nome di un membro di un gruppo di posta.\\ + \const{T\_MR} & nome di un cambiamento di nome per la posta.\\ + \const{T\_NULL} & record nullo.\\ + \const{T\_WKS} & servizio noto.\\ + \const{T\_PTR} & risoluzione inversa di un indirizzo numerico.\\ + \const{T\_HINFO} & informazione sulla stazione.\\ + \const{T\_MINFO} & informazione sulla casella di posta.\\ + \const{T\_MX} & server cui instradare la posta per il dominio.\\ + \const{T\_TXT} & stringhe di testo (libere).\\ + \const{T\_RP} & nome di un responsabile (\textit{responsible person}).\\ + \const{T\_AFSDB} & database per una cella AFS.\\ + \const{T\_X25} & indirizzo di chiamata per X.25.\\ + \const{T\_ISDN} & indirizzo di chiamata per ISDN.\\ + \const{T\_RT} & router.\\ + \const{T\_NSAP} & indirizzo NSAP.\\ + \const{T\_NSAP\_PTR}& risoluzione inversa per NSAP (deprecato).\\ + \const{T\_SIG} & firma digitale di sicurezza.\\ + \const{T\_KEY} & chiave per firma.\\ + \const{T\_PX} & corrispondenza per la posta X.400.\\ + \const{T\_GPOS} & posizione grografica.\\ + \const{T\_AAAA} & indirizzo IPv6.\\ + \const{T\_LOC} & informazione di collocazione.\\ + \const{T\_NXT} & dominio successivo.\\ + \const{T\_EID} & identificatore di punto conclusivo.\\ + \const{T\_NIMLOC}& posizionatore \textit{nimrod}.\\ + \const{T\_SRV} & servizio.\\ + \const{T\_ATMA} & indirizzo ATM.\\ + \const{T\_NAPTR} & puntatore ad una \textit{naming authority} .\\ + \const{T\_TSIG} & firma di transazione.\\ + \const{T\_IXFR} & trasferimento di zona incrementale.\\ + \const{T\_AXFR} & trasferimento di zona di autorità.\\ + \const{T\_MAILB} & trasferimento di record di caselle di posta.\\ + \const{T\_MAILA} & trasferimento di record di server di posta.\\ + \const{T\_ANY} & valore generico.\\ + \hline + \end{tabular} + \caption{Costanti identificative del tipo di record per l'argomento + \param{type} di \func{res\_query}.} + \label{tab:DNS_record_type} +\end{table} + + +L'elenco di tab.~\ref{tab:DNS_record_type} è quello di \textsl{tutti} i +\textit{resource record} definiti, con una breve descrizione del relativo +significato. Di tutti questi però viene impiegato correntemente solo un +piccolo sottoinsieme, alcuni sono obsoleti ed altri fanno riferimento a dati +applicativi che non ci interessano non avendo nulla a che fare con la +risoluzione degli indirizzi IP, pertanto non entreremo nei dettagli del +significato di tutti i \textit{resource record}, ma solo di quelli usati dalle +funzioni del \textit{resolver}. Questi sono sostanzialmente i seguenti (per +indicarli si è usata la notazione dei file di zona di BIND): +\begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}} +\item[\texttt{A}] viene usato per indicare la corripondenza fra un nome a + dominio ed un indirizzo IPv4; ad esempio la corrispondenza fra + \texttt{dodds.truelite.it} e l'indirizzo IP \texttt{62.48.34.25}. +\item[\texttt{AAAA}] viene usato per indicare la corrispondenza fra un nome a + dominio ed un indirizzo IPv6; è chiamato in questo modo dato che la + dimensione di un indirizzo IPv6 è quattro volte quella di un indirizzo IPv4. +\item[\texttt{PTR}] per fornire la corripondenza inversa fra un indirizzo IP + ed un nome a dominio ad esso associato si utilizza questo tipo di record (il + cui nome sta per \textit{pointer}). +\item[\texttt{CNAME}] qualora si abbiamo più nomi che corrispondono allo + stesso indirizzo (come ad esempio \texttt{www.truelite.it}, o + \texttt{sources.truelite.it}, che fanno sempre riferimento a + \texttt{dodds.truelite.it}) si può usare questo tipo di record per creare + degli \textit{alias} in modo da associare un qualunque altro nome al + \textsl{nome canonico} della macchina (si chiama così quello associato al + record \texttt{A}). +\end{basedescript} + +Come accennato in caso di successo le due funzioni di richiesta restituiscono +il risultato della interrogazione al server, in caso di insuccesso l'errore +invece viene segnalato da un valore di ritorno pari a -1, ma in questo caso, +non può essere utilizzata la variabile \var{errno} per riportare un codice di +errore, in quanto questo viene impostato per ciascuna delle chiamate al +sistema utilizzate dalle funzioni del \textit{resolver}, non avrà alcun +significato nell'indicare quale parte del procedimento di risoluzione è +fallita. + +Per questo motivo è stata definita una variabile di errore separata, +\var{h\_errno}, che viene utilizzata dalle funzioni del \textit{resolver} per +indicare quale problema ha causato il fallimento della risoluzione del nome. +Ad essa si può accedere una volta che la si dichiara con: +\includecodesnip{listati/herrno.c} +ed i valori che può assumere, con il relativo significato, sono riportati in +tab.~\ref{tab:h_errno_values}. + +\begin{table}[!htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{10cm}|} + \hline + \textbf{Costante} & \textbf{Significato} \\ + \hline + \hline + \const{HOST\_NOT\_FOUND} & l'indirizzo richiesto non è valido e la + macchina indicata è sconosciuta. \\ + \const{NO\_ADDRESS} & il nome a dominio richiesto è valido, ma non ha + un indirizzo associato ad esso + (alternativamente può essere indicato come + \const{NO\_DATA}). \\ + \const{NO\_RECOVERY} & si è avuto un errore non recuperabile + nell'interrogazione di un server DNS. \\ + \const{TRY\_AGAIN} & si è avuto un errore temporaneo + nell'interrogazione di un server DNS, si può + ritentare l'interrogazione in un secondo + tempo. \\ + \hline + \end{tabular} + \caption{Valori possibili della variabile \var{h\_errno}.} + \label{tab:h_errno_values} +\end{table} + +Insieme alla nuova variabile vengono definite anche due nuove funzioni per +stampare l'errore a video, analoghe a quelle di sez.~\ref{sec:sys_strerror} +per \var{errno}, ma che usano il valore di \var{h\_errno}; la prima è +\funcd{herror} ed il suo prototipo è: +\begin{functions} +\headdecl{netdb.h} +\funcdecl{void herror(const char *string)} + +Stampa un errore di risoluzione. +\end{functions} + +La funzione è l'analoga di \func{perror} e stampa sullo standard error un +messaggio di errore corrispondente al valore corrente di \var{h\_errno}, a cui +viene anteposta la stringa \param{string} passata come argomento. La seconda +funzione è \funcd{hstrerror} ed il suo prototipo è: +\begin{functions} +\headdecl{netdb.h} +\funcdecl{const char *hstrerror(int err)} + +Restituisce una stringa corripondente ad un errore di risoluzione. +\end{functions} +\noindent che, come l'analoga \func{strerror}, restituise una stringa con un +messaggio di errore già formattato, corrispondente al codice passato come +argomento (che si presume sia dato da \var{h\_errno}). + + + \subsection{La risoluzione dei nomi a dominio} \label{sec:sock_gethostbyname} -Dato che la principale funzionalità del \textit{resolver} resta quella di -risolvere i nomi a dominio in indirizzi IP, vedremo per prime 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 suo -prototipo è: +La principale funzionalità del \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 suo prototipo è: \begin{prototype}{netdb.h} {struct hostent *gethostbyname(const char *name)} Determina l'indirizzo associato al nome a dominio \param{name}. \bodydesc{La funzione restituisce in caso di successo il puntatore ad una - struttura di tipo \struct{hostent} contente i dati associati al nome a - dominio o un puntatore nullo in caso di errore.} + struttura di tipo \struct{hostent} contenente i dati associati al nome a + dominio, o un puntatore nullo in caso di errore.} \end{prototype} La funzione prende come argomento una stringa \param{name} contenente il nome a dominio che si vuole risolvere, in caso di successo i dati ad esso relativi vengono memorizzati in una opportuna struttura \struct{hostent} la cui -definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. In caso di -insuccesso l'errore viene segnalato da un valore nullo del puntatore, ma in -questo caso, a differenza delle funzioni viste finora, non viene utilizzata la -variabile \var{errno} per riportare un codice di errore, in quanto questo -dipende solo dalle sottostanti chiamate al sistema e può non avere nessun -significato nell'indicare quale parte del procedimento di risoluzione è -fallita. +definizione è riportata in fig.~\ref{fig:sock_hostent_struct}. \begin{figure}[!htb] \footnotesize \centering @@ -214,58 +643,10 @@ fallita. \label{fig:sock_hostent_struct} \end{figure} -Per questo motivo all'interno del resolver è stata definita una apposita -variabile di errore, \var{h\_errno} che viene utilizzata dalle funzioni di -libreria per indicare quale problema ha causato il fallimento della -risoluzione del nome. Ad essa si può accedere una volta che la si dichiara -con: -\includecodesnip{listati/herrno.c} -ed i valori che può assumere sono i seguenti: -\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}} -\item[\const{HOST\_NOT\_FOUND}] l'indirizzo richiesto non è valido e la - macchina indicata è sconosciuta. -\item[\const{NO\_ADDRESS}] il nome a dominio richiesto è valido, ma non ha un - indirizzo associato ad esso (alternativamente può essere indicato come - \const{NO\_DATA}). -\item[\const{NO\_RECOVERY}] si è avuto un errore non recuperabile - nell'interrogazione di un server DNS. -\item[\const{TRY\_AGAIN}] si è avuto un errore temporaneo nell'interrogazione - di un server DNS, si può ritentare l'interrogazione in un secondo tempo. -\end{basedescript} - -Per capire meglio il contenuto della struttura \struct{hostent} conviene -spendere alcune parole sul funzionamento del DNS. Questo in sostanza è un -database distribuito organizzato in maniera gerarchica, interrogando il quale -si possono avere una serie di informazioni, la principale delle quali è la -corrispondenza fra un nome (a dominio) ed indirizzo IP. Un server DNS -contiene comunque una serie di altre informazioni; ciascuna voce nel database -viene chiamata \textit{resource record} e vi è associato un certo -\textsl{tipo}, identificato da una sigla. Per quanto ci interessa i tipi di -\textit{resource record} che vengono utilizzati dal \textit{resolver} sono -sostanzialmente i seguenti: -\begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}} -\item[\texttt{A}] indica la corripondenza fra un nome a dominio ed un - indirizzo IPv4, ad esempio la corrispondenza fra \texttt{dodds.truelite.it} - e l'indirizzo IP \texttt{62.48.34.25}. -\item[\texttt{AAAA}] chiamato in questo modo dato che la dimensione è quattro - volte quella di un indirizzo IPv4, questo record contiene la corrispondenza - fra un nome a dominio ed un indirizzo IPv6. -\item[\texttt{PTR}] per provvedere la mappatura inversa fra un indirizzo IP ed - un nome a dominio si utilizza invece questo tipo di record (il cui nome sta - per \textit{pointer}). -\item[\texttt{CNAME}] qualora si abbiamo più nomi con i quali si voglia - indicare lo stesso indirizzo (ad esempio \texttt{www.truelite.it}, o - \texttt{sources.truelite.it}, che comunque fanno sempre riferimento alla - macchina \texttt{dodds.truelite.it}) si può usare questo tipo di record per - creare degli \textit{alias} in modo da associare un qualunque altro nome al - \textsl{nome canonico} della macchina (quello associato al record - \texttt{A}). -\end{basedescript} - Quando un programma chiama \func{gethostbyname} e questa usa il DNS per -effettuare la risoluzione del nome, è con i valori di questi record che -vengono riempite le varie parti della struttura \struct{hostent}. Il primo -campo della struttura, \var{h\_name} contiene sempre il \textsl{nome +effettuare la risoluzione del nome, è con i valori contenuti nei relativi +record che vengono riempite le varie parti della struttura \struct{hostent}. +Il primo campo della struttura, \var{h\_name} contiene sempre il \textsl{nome canonico}, che nel caso del DNS è appunto il nome associato ad un record \texttt{A}. Il secondo campo della struttura, \var{h\_aliases}, invece è un puntatore ad vettore di puntatori, terminato da un puntatore nullo. Ciascun @@ -276,25 +657,183 @@ DNS vengono inseriti come record di tipo \texttt{CNAME}). Il terzo campo della struttura, \var{h\_addrtype}, indica il tipo di indirizzo che è stato restituito, e può assumere soltanto i valori \const{AF\_INET} o \const{AF\_INET6}, mentre il quarto campo, \var{h\_length}, indica la -lunghezza dell'indirizzo stesso in byte. Infine il campo \var{h\_addr\_list} è -il puntatore ad un vettore di puntatori ai singoli indirizzi; il vettore è -terminato da un puntatore nullo. Inoltre, come illustrato in -fig.~\ref{fig:sock_hostent_struct}, viene definito il campo \var{h\_addr} come -sinonimo di \code{h\_addr\_list[0]}, cioè un riferimento diretto al primo -indirizzo della lista. - +lunghezza dell'indirizzo stesso in byte. +Infine il campo \var{h\_addr\_list} è il puntatore ad un vettore di puntatori +ai singoli indirizzi; il vettore è terminato da un puntatore nullo. Inoltre, +come illustrato in fig.~\ref{fig:sock_hostent_struct}, viene definito il campo +\var{h\_addr} come sinonimo di \code{h\_addr\_list[0]}, cioè un riferimento +diretto al primo indirizzo della lista. Oltre ai normali nomi a dominio la funzione accetta come argomento \param{name} anche indirizzi numerici, in formato dotted decimal per IPv4 o -con la notazione illustrata in sez.~\ref{sec:IP_ipv6_notation}. In tal caso -\func{gethostbyname} non eseguirà nessuna interrogazione remota, ma si -limiterà a copiare la stringa nel campo \var{h\_name} ed a creare la -corrispondente struttura \var{in\_addr} da indirizzara con +con la notazione illustrata in sez.~\ref{sec:IP_ipv6_notation} per IPv6. In +tal caso \func{gethostbyname} non eseguirà nessuna interrogazione remota, ma +si limiterà a copiare la stringa nel campo \var{h\_name} ed a creare la +corrispondente struttura \var{in\_addr} da indirizzare con \code{h\_addr\_list[0]}. +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 resolver; dato che questo non è molto comodo è stata +definita un'altra funzione, \funcd{gethostbyname2}, il cui prototipo è: +\begin{functions} + \headdecl{netdb.h} + \headdecl{sys/socket.h} + \funcdecl{struct hostent *gethostbyname2(const char *name, int af)} + +Determina l'indirizzo di tipo \param{af} associato al nome a dominio +\param{name}. + +\bodydesc{La funzione restituisce in caso di successo il puntatore ad una + struttura di tipo \struct{hostent} contenente i dati associati al nome a + dominio, o un puntatore nullo in caso di errore.} +\end{functions} + +In questo caso la funzione prende un secondo argomento \param{af} che indica +(i soli valori consentiti sono \const{AF\_INET} o \const{AF\_INET6}, per +questo è necessario l'uso di \texttt{sys/socket.h}) la famiglia di indirizzi +che dovrà essere utilizzata nei risultati restituiti dalla funzione. Per tutto +il resto la funzione è identica a \func{gethostbyname}, ed identici sono i +suoi risultati. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \includecodesample{listati/myhost.c} + \end{minipage} + \normalsize + \caption{Esempio di codice per la risoluzione di un indirizzo.} + \label{fig:myhost_example} +\end{figure} + +Vediamo allora un primo esempio dell'uso delle funzioni di risoluzione, in +fig.~\ref{fig:myhost_example} è riportato un estratto del codice di un +programma che esegue una semplice interrogazione al \textit{resolver} usando +\func{gethostbyname} e poi ne stampa a video i risultati. Al solito il +sorgente completo, he comprende il trattamento delle opzioni ed una funzione +per stampare un messaggio di aiuto, è nel file \texttt{myhost.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 +(\texttt{\small 16}) si limita a chiamare \func{gethostbyname}, ricendo il +risultato nel puntatore \var{data}. Questo (\texttt{\small 17--20}) viene +controllato per rilevare eventuali errori, nel qual caso il programma esce +dopo aver stampato un messaggio con \func{herror}. + +Se invece la risoluzione è andata a buon fine si inizia (\texttt{\small 21}) +con lo stampare il nome canonico, dopo di che (\texttt{\small 22--26}) si +stampano eventuali altri nomi. Per questo prima (\texttt{\small 22}) si prende +il puntatore alla cima della lista che contiene i nomi e poi (\texttt{\small + 23--26}) si esegue un ciclo che sarà ripetuto fin tanto che nella lista si +troveranno dei puntatori validi\footnote{si ricordi che la lista viene + terminata da un puntatore nullo.} per le stringhe dei nomi; prima +(\texttt{\small 24}) si stamperà la stringa e poi (\texttt{\small 25}) si +provvederà ad incrementare il puntatore per passare al successivo elemento +della lista. + +Una volta stampati i nomi si passerà a stampare gli indirizzi, il primo passo +(\texttt{\small 27--34}) è allora quello di riconoscere il tipo di indirizzo +sulla base del valore del campo \var{h\_addrtype}, stampandolo a video. Si è +anche previsto di stampare un errore nel caso (che non dovrebbe mai accadere) +di un indirizzo non valido. + +Infine (\texttt{\small 35--40}) si stamperanno i valori degli indirizzi, di +nuovo (\texttt{\small 35}) si inizializzerà un puntatore alla cima della lista +e si eseguirà un ciclo fintanto che questo punterà ad indirizzi validi in +maniera analoga a quanto fatto in precedenza per i nomi a dominio. Si noti +come, essendo il campo \var{h\_addr\_list} un puntatore ad strutture di +indirizzi generiche, questo sia ancora di tipo \texttt{char **} e si possa +riutilizzare lo stesso puntatore usato per i nomi. + +Per ciascun indirizzo valido si provvederà (\texttt{\small 37}) ad una +conversione con la funzione \func{inet\_ntop} (vedi +sez.~\ref{sec:sock_addr_func}) passandole gli opportuni argomenti, questa +restituirà la stringa da stampare (\texttt{\small 38}) con il valore +dell'indirizzo in \var{buffer}, che si è avuto la cura di dichiarare +inizialmente (\texttt{\small 10}) con dimensioni adeguate; dato che la +funzione è in grado di tenere conto automaticamente del tipo di indirizzo non +ci sono precauzioni particolari da prendere.\footnote{volendo essere pignoli + si dovrebbe controllarne lo stato di uscita, lo si è tralasciato per non + appesantire il codice, dato che in caso di indirizzi non validi si sarebbe + 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 +caratterizzate dall'avere un suffisso \texttt{\_r}, pertanto avremo le due +funzioni \funcd{gethostbyname\_r} e \funcd{gethostbyname2\_r} i cui prototipi +sono: +\begin{functions} + \headdecl{netdb.h} + \headdecl{sys/socket.h} + \funcdecl{int gethostbyname\_r(const char *name, struct hostent *ret, + char *buf, size\_t buflen, struct hostent **result, int *h\_errnop)} + \funcdecl{int gethostbyname2\_r(const char *name, int af, + struct hostent *ret, char *buf, size\_t buflen, + struct hostent **result, int *h\_errnop)} + + Versioni rientranti delle funzioni \func{gethostbyname} e + \func{gethostbyname2}. + + \bodydesc{Le funzioni restituiscono 0 in caso di successo ed un valore + 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 +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}. + +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 +puntatatore che si userà per accedere i dati con \param{result}. + +In caso di successo entrambe le funzioni restituiscono un valore nullo, +altrimenti restituiscono un codice di errore negativo e all'indirizzo puntato +da \param{result} sarà salvato un puntatore nullo, mentre a quello puntato da +\param{h\_errnop} sarà salvato il valore del codice di errore, dato che per +essere rientrante la funzione non può la variabile globale \var{h\_errno}. In +questo caso il codice di errore, oltre ai valori di +tab.~\ref{tab:h_errno_values}, può avere anche quello di \errcode{ERANGE} +qualora il buffer allocato su \param{buf} non sia sufficiente a contenere i +dati, in tal caso si dovrà semplicemente ripetere l'esecuzione della funzione +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 +è: +\begin{prototype}{netdb.h} +{void sethostent(int stayopen)} + +Richiede l'uso di connessioni per le interrogazioni ad un server DNS. + +\bodydesc{La funzione non restituisce nulla.} +\end{prototype} + + +\subsection{Altre funzioni di gestione dei nomi} +\label{sec:sock_name_services} +Quelle illustrate nella sezione precedente sono le funzioni classiche per la +risoluzione di nomi ed indirizzi IP, ma abbiamo già visto in