X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=socket.tex;h=e20c38800ce3e087de70946678e1a2854d80be31;hp=b379719cf38d3c63289c30fc4694cdf9ed28e649;hb=d99b4995b23505a9afde30adf3a716aa7a55f0e9;hpb=a93a0bac951085a52c4b33c42a607fc81f6868d2 diff --git a/socket.tex b/socket.tex index b379719..e20c388 100644 --- a/socket.tex +++ b/socket.tex @@ -117,7 +117,7 @@ altro nome con cui si indicano i domini. A ciascun tipo di dominio corrisponde un analogo nome simbolico che inizia per \texttt{AF\_} da \textit{address family}, e che identifica il formato degli -indirizzi usati in quel dominio; le man pages di linux si riferiscono a questi +indirizzi usati in quel dominio; le man pages di Linux si riferiscono a questi anche come \textit{name space}, (nome che però il manuale della glibc riserva ai domini) e che identifica il formato degli indirizzi usati in quel dominio. @@ -130,7 +130,7 @@ supportino diverse strutture di indirizzi, per cui nella pratica questi due nomi sono equivalenti e corrispondono agli stessi valori. I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di -indirizzi sono definiti dall'header \textit{socket.h}. In linux le famiglie di +indirizzi sono definiti dall'header \textit{socket.h}. In Linux le famiglie di protocolli disponibili sono riportate in \ntab. \begin{table}[htb] @@ -150,13 +150,13 @@ protocolli disponibili sono riportate in \ntab. PF\_APPLETALK & Appletalk & ddp(7) \\ PF\_PACKET & Low level packet interface & packet(7) \\ \end{tabular} - \caption{Famiglie di protocolli definiti in linux} + \caption{Famiglie di protocolli definiti in Linux} \label{tab:net_pf_names} \end{table} Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad esempio in generale tutti i socket di tipo \texttt{SOCK\_RAW} possono essere -creati solo da processi che hanno i provilegi di root (cioè effective uid +creati solo da processi che hanno i privilegi di root (cioè effective uid uguale a zero) o la capability \texttt{CAP\_NET\_RAW}. @@ -166,7 +166,7 @@ uguale a zero) o la capability \texttt{CAP\_NET\_RAW}. La scelta di un dominio non comporta però la scelta dello stile di comunicazione, questo infatti viene a dipendere dal protocollo che si andrà ad utilizzare fra quelli disponibili nella famiglia scelta. Le API permettono di -scegliere lo stile di comunicazione indicando il tipo di socket; linux e le +scegliere lo stile di comunicazione indicando il tipo di socket; Linux e le glibc mettono a disposizione i seguenti tipi di socket (che il manuale della glibc chiama \textit{styles}) definiti come \texttt{int} in \texttt{socket.h}: @@ -268,7 +268,7 @@ in \nfig: \begin{figure}[!htbp] \footnotesize - \begin{lstlisting}{} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} struct sockaddr { sa_family_t sa_family; /* address family: AF_xxx */ char sa_data[14]; /* address (protocol-specific) */ @@ -284,7 +284,7 @@ invocano dette funzioni passando l'indirizzo di un protocollo specifico occorrerà eseguire un casting del relativo puntatore. I tipi di dati che compongono la struttura sono stabiliti dallo standard -Posix.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono +POSIX.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono definiti; la struttura è invece definita nell'include file \texttt{sys/socket.h} @@ -314,14 +314,14 @@ definiti; la struttura \hline \end{tabular} \caption{Tipi di dati usati nelle strutture degli indirizzi, secondo quanto - stabilito dallo standard Posix.1g} + stabilito dallo standard POSIX.1g} \label{tab:sock_data_types} \end{table} In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro aggiuntivo \texttt{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi libri). Questo campo non verrebbe usato direttamente dal programmatore e non è -richiesto dallo standard Posix.1g, in linux pertanto non sussiste. Il campo +richiesto dallo standard POSIX.1g, in Linux pertanto non sussiste. Il campo \texttt{sa\_family\_t} era storicamente un \texttt{unsigned short}. Dal punto di vista del programmatore l'unico uso di questa struttura è quello @@ -340,12 +340,12 @@ I socket di tipo \texttt{PF\_INET} vengono usati per la comunicazione attraverso internet; la struttura per gli indirizzi per un socket internet (IPv4) è definita come \texttt{sockaddr\_in} nell'header file \texttt{netinet/in.h} e secondo le man page ha la forma mostrata in \nfig, -conforme allo standard Posix.1g. +conforme allo standard POSIX.1g. \begin{figure}[!htbp] \footnotesize - \begin{lstlisting}{} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} struct sockaddr_in { sa_family_t sin_family; /* address family: AF_INET */ u_int16_t sin_port; /* port in network byte order */ @@ -377,7 +377,7 @@ usare la funzione \texttt{bind} su queste porte. Il membro \texttt{sin\_addr} contiene l'indirizzo internet dell'altro capo della comunicazione, e viene acceduto sia come struttura (un resto di una -implementazione precedente in cui questa era una union usata per accedere alle +implementazione precedente in cui questa era una \texttt{union} usata per accedere alle diverse classi di indirizzi) che come intero. Infine è da sottolineare che sia gli indirizzi che i numeri di porta devono @@ -390,14 +390,14 @@ problema e le relative soluzioni). \subsection{La struttura degli indirizzi IPv6} \label{sec:sock_sa_ipv6} -Essendo IPv6 una estenzione di IPv4 i socket di tipo \texttt{PF\_INET6} sono +Essendo IPv6 una estensione di IPv4 i socket di tipo \texttt{PF\_INET6} sono sostanzialmente identici ai precedenti; la parte in cui si trovano praticamente tutte le differenze è quella della struttura degli indirizzi. La struttura degli indirizzi è definita ancora in \texttt{netinet/in.h}. \begin{figure}[!htbp] \footnotesize - \begin{lstlisting}{} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} struct sockaddr_in6 { u_int16_t sin6_family; /* AF_INET6 */ u_int16_t sin6_port; /* port number */ @@ -417,11 +417,11 @@ struct in6_addr { Il campo \texttt{sin6\_family} deve essere sempre settato ad \texttt{AF\_INET6}, il campo \texttt{sin6\_port} è analogo a quello di IPv4 e -segue le stesse regole; il campo \texttt{sin6\_flowinfo} è a dua volta diviso +segue le stesse regole; il campo \texttt{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 \secref{sec:appA_ipv6}) ed il loro uso è sperimentale. +(vedi \secref{sec:IP_ipv6head}) ed il loro uso è sperimentale. Il campo \texttt{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6, infine il campo \texttt{sin6\_scope\_id} è un campo introdotto con il kernel @@ -444,7 +444,7 @@ definita nel file di header \texttt{sys/un.h}. \begin{figure}[!htbp] \footnotesize - \begin{lstlisting}{} + \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} #define UNIX_PATH_MAX 108 struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ @@ -498,7 +498,7 @@ utile anche in seguito. \subsection{La \textit{endianess}} \label{sec:sock_endianess} -La rappresentazione di un numbero binario in un computer può essere fatta in +La rappresentazione di un numero binario in un computer può essere fatta in due modi, chiamati rispettivamente \textit{big endian} e \textit{little endian} a seconda di come i singoli bit vengono aggregati per formare le variabili intere (in diretta corrispondenza a come sono poi in realtà cablati @@ -515,14 +515,16 @@ numero. Il caso opposto, in cui si parte dal bit meno significativo per lo stesso motivo \textit{big endian}. La \textit{endianess} di un computer dipende essenzialmente dalla architettura -hardware usata; intel e digital usano il little endian, motorola, ibm, sun +hardware usata; Intel e Digital usano il little endian, Motorola, IBM, Sun (sostanzialmente tutti gli altri) usano il big endian. Il formato della rete è -anch'esso big endian. Esistono poi anche dei processori che possono scegliere -il tipo di formato all'avvio e alcuni, come il PowerPC o l'intel i860, possono -pure passare da un tipo all'altro con una specifica istruzione; in ogni caso -in linux l'ordinamanento è definito dall'archiettura e anche se questi -cambiamenti sono possibili anche dopo che il sistema è avviato, non vengono -mai eseguiti. +anch'esso big endian, quello del bus PCI è little endian, quello del bus VME è +big endian. + +Esistono poi anche dei processori che possono scegliere il tipo di formato +all'avvio e alcuni, come il PowerPC o l'Intel i860, possono pure passare da un +tipo di ordinamento all'altro con una specifica istruzione; in ogni caso in +Linux l'ordinamento è definito dall'architettura e anche se questi cambiamenti +sono possibili anche dopo che il sistema è avviato, non vengono mai eseguiti. \subsection{Le funzioni per il riordinamento} \label{sec:sock_func_ord} @@ -531,7 +533,7 @@ Il problema connesso all'endianess di architettura all'altra i dati vengono interpretati in maniera diversa, e ad esempio nel caso dell'intero a 16 bit ci si ritroverà con i due bytes in cui è suddiviso scambiati di posto, e ne sarà quindi invertito l'ordine di lettura -per cui, per riavere il valore originale dovrenno essere rovesciati. +per cui, per riavere il valore originale dovranno essere rovesciati. Per questo motivo si usano le seguenti funzioni di conversione che servono a tener conto automaticamente della possibile differenza fra l'ordinamento usato @@ -543,7 +545,7 @@ funzioni sono: quello della rete. \end{prototype} \begin{prototype}{netinet/in.h} -{unsigned sort int htons(unsigned short int hostshort)} +{unsigned short int htons(unsigned short int hostshort)} Converte l'intero a 16 bit \texttt{hostshort} dal formato della macchina a quello della rete. \end{prototype} @@ -575,7 +577,7 @@ codice su tutte le architetture. Un secondo insieme di funzioni di manipolazione serve per passare dal formato binario usato nelle strutture degli indirizzi alla rappresentazione dei numeri -IP che si usa normalente. +IP che si usa normalmente. Le prime tre funzioni di manipolazione riguardano la conversione degli indirizzi IPv4 da una stringa in cui il numero di IP è espresso secondo la @@ -613,48 +615,59 @@ indicare la stringa. Dette funzioni sono: Le tre funzioni precedenti sono limitate solo ad indirizzi IPv4, per questo motivo è preferibile usare le due nuove funzioni \texttt{inet\_pton} e -\texttt{inet\_ntop} che possono convertire anche gli indirizzi IPv6 (secondo -lo schema in \nfig). Anche in questo caso le lettere $n$ e $p$ sono degli -mnemonici per ricordare il tipo di conversione effettuata e stanno per -\textit{presentation} e \textit{numeric}. +\texttt{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in +questo caso le lettere $n$ e $p$ sono degli mnemonici per ricordare il tipo di +conversione effettuata e stanno per \textit{presentation} e \textit{numeric}. -\begin{figure}[htb] - \centering +% \begin{figure}[htb] +% \centering - \caption{Schema della rappresentazioni utilizzate dalle funzioni di - conversione \texttt{inet\_pton} e \texttt{inet\_ntop} } - \label{fig:sock_inet_conv_func} +% \caption{Schema della rappresentazioni utilizzate dalle funzioni di +% conversione \texttt{inet\_pton} e \texttt{inet\_ntop} } +% \label{fig:sock_inet_conv_func} -\end{figure} +% \end{figure} -Entrambe le funzioni accettano l'argomento \texttt{family} che indica il tipo -di indirizzo e può essere \texttt{AF\_INET} o \texttt{AF\_INET6}. Se la -famiglia indicata non è valida entrambe le funzioni ritornano un valore -negativo e settano la variabile \texttt{errno} al valore -\texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i seguenti: +Entrambe le funzioni accettano l'argomento \texttt{af} che indica il tipo di +indirizzo e può essere \texttt{AF\_INET} o \texttt{AF\_INET6}. Se la famiglia +indicata non è valida entrambe le funzioni settano la variabile \texttt{errno} +al valore \texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i +seguenti: \begin{prototype}{sys/socket.h} -{int inet\_pton(int family, const char *src, void *dest)} - Converte la stringa puntata da \texttt{src} nell'indirizzo binario da - memorizzare all'indirizzo puntato da \texttt{dest}, restituendo 0 in caso di - successo e 1 in caso di fallimento. + {int inet\_pton(int af, const char *src, void *addr\_ptr)} Converte la + stringa puntata da \texttt{src} nell'indirizzo IP da memorizzare + all'indirizzo puntato da \texttt{addr\_ptr}, la funzione restituisce un + valore positivo in caso di successo, e zero se la stringa non rappresenta un + indirizzo valido, e negativo se \var{af} specifica una famiglia di indirizzi + non valida. \end{prototype} \begin{prototype}{sys/socket.h} -{char *inet\_ntop(int family, const void *src, char *dest, size\_t len)} - Converte la struttura dell'indirizzo puntata da \texttt{src} in una stringa - che viene copiata nel buffer puntato dall'indirizzo \texttt{dest}; questo - deve essere preallocato dall'utente e la lunghezza deve essere almeno + {char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)} + Converte la struttura dell'indirizzo puntata da \texttt{addr\_ptr} in una + stringa che viene copiata nel buffer puntato dall'indirizzo \texttt{dest}; + questo deve essere preallocato dall'utente e la lunghezza deve essere almeno \texttt{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e \texttt{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve comunque venire specificata attraverso il parametro \texttt{len}. - + La funzione restituisce un puntatore non nullo a \texttt{dest} in caso di successo e un puntatore nullo in caso di fallimento, in quest'ultimo caso viene settata la variabile \texttt{errno} con il valore \texttt{ENOSPC} in caso le dimensioni dell'indirizzo eccedano la lunghezza specificata da - \texttt{len}. + \texttt{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia una famiglia di + indirizzi valida. \end{prototype} +Gli indirizzi vengono cnovertiti da/alle rispettive strutture di indirizzo +(\var{struct in\_addr} per IPv4, e \var{struct in6\_addr} per IPv6), che +devono essere precedentemente allocate e passate attraverso il puntatore +\var{addr\_ptr}; il parametro \var{dest} di \func{inet\_ntop} non può essere +nullo e deve essere allocato precedentemente. + +Il formato usato per gli indirizzi in formato di presentazione è la notazione +\textit{dotted decimal} per IPv4 e quella descritta in +\secref{sec:IP_ipv6_notation} per IPv6. \section{Il comportamento delle funzioni di I/O} \label{sec:sock_io_behav}