X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=socket.tex;h=c69c9ee860e0799099c86198a178d593fc81a6ea;hp=b8538ab3be3e1074126877f5e0e6c2c12cbe4640;hb=0c4a9ed958f4797e1cf4dc90e0c0358e302956f5;hpb=68fa6cc298c7449a011865c55c5af979963a2753 diff --git a/socket.tex b/socket.tex index b8538ab..c69c9ee 100644 --- a/socket.tex +++ b/socket.tex @@ -1,6 +1,6 @@ %% socket.tex %% -%% Copyright (C) 2000-2011 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2015 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Un preambolo", @@ -238,8 +238,8 @@ valori numerici.\footnote{in Linux, come si può verificare andando a guardare lo stesso nome.} I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di -indirizzi, sono definiti dall'header \texttt{socket.h}. Un elenco delle -famiglie di protocolli disponibili in Linux è riportato in +indirizzi, sono definiti dall'\textit{header file} \headfile{socket.h}. Un +elenco delle famiglie di protocolli disponibili in Linux è riportato in tab.~\ref{tab:net_pf_names}.\footnote{l'elenco indica tutti i protocolli definiti; fra questi però saranno utilizzabili solo quelli per i quali si è compilato il supporto nel kernel (o si sono caricati gli opportuni moduli), @@ -249,7 +249,7 @@ tab.~\ref{tab:net_pf_names}.\footnote{l'elenco indica tutti i protocolli Si tenga presente che non tutte le famiglie di protocolli sono utilizzabili dall'utente generico, ad esempio in generale tutti i socket di tipo \const{SOCK\_RAW} possono essere creati solo da processi che hanno i privilegi -di amministratore (cioè con user-ID effettivo uguale a zero) o dotati della +di amministratore (cioè con \ids{UID} effettivo uguale a zero) o dotati della \itindex{capabilities} \textit{capability} \const{CAP\_NET\_RAW}. @@ -262,7 +262,7 @@ utilizzare fra quelli disponibili nella famiglia scelta. L'interfaccia dei socket permette di scegliere lo stile di comunicazione indicando il tipo di socket con l'argomento \param{type} di \func{socket}. Linux mette a disposizione vari tipi di socket (che corrispondono a quelli che il manuale -della \acr{glibc} \cite{glibc} chiama \textit{styles}) identificati dalle +della \acr{glibc} \cite{GlibcMan} chiama \textit{styles}) identificati dalle seguenti costanti:\footnote{le pagine di manuale POSIX riportano solo i primi tre tipi, Linux supporta anche gli altri, come si può verificare nel file \texttt{include/linux/net.h} dei sorgenti del kernel.} @@ -293,10 +293,30 @@ seguenti costanti:\footnote{le pagine di manuale POSIX riportano solo i primi pertanto non ne parleremo ulteriormente.} \end{basedescript} -Si tenga presente che non tutte le combinazioni fra una famiglia di protocolli -e un tipo di socket sono valide, in quanto non è detto che in una famiglia -esista un protocollo per ciascuno dei diversi stili di comunicazione appena -elencati. +A partire dal kernel 2.6.27 l'argomento \param{type} della funzione +\func{socket} assume un significato ulteriore perché può essere utlizzato per +impostare dei flag relativi alle caratteristiche generali del \textit{socket} +non strettamente attinenti all'indicazione del tipo secondo i valori appena +illustrati. Essi infatti possono essere combinati con un OR aritmetico delle +ulteriori costanti: +\begin{basedescript}{\desclabelwidth{2.9cm}\desclabelstyle{\nextlinelabel}} +\item[\const{SOCK\_CLOEXEC}] imposta il flag di \textit{close-on-exec} sul + file descriptor del socket, ottenendo lo stesso effetto del flag + \const{O\_CLOEXEC} di \func{open} (vedi tab.~\ref{tab:open_operation_flag}), + di cui costituisce l'analogo. + +\item[\const{SOCK\_NONBLOCK}] crea il socket in modalità non-bloccante, con + effetti identici ad una successiva chiamata a \func{fcntl} per impostare il + flag di \const{O\_NONBLOCK} sul file descriptor (si faccia di nuovo + riferimenti al significato di quest'ultimo come spiegato in + tab.~\ref{tab:open_operation_flag}). +\end{basedescript} + + +Si tenga presente inoltre che non tutte le combinazioni fra una famiglia di +protocolli e un tipo di socket sono valide, in quanto non è detto che in una +famiglia esista un protocollo per ciascuno dei diversi stili di comunicazione +appena elencati. \begin{table}[htb] \footnotesize @@ -378,7 +398,7 @@ una struttura generica per gli indirizzi dei socket, \struct{sockaddr}, che si \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/sockaddr.h} \end{minipage} \caption{La struttura generica degli indirizzi dei socket @@ -394,7 +414,7 @@ occorrerà eseguire una conversione del relativo puntatore. I tipi di dati che compongono la struttura sono stabiliti dallo standard POSIX.1g e li abbiamo riassunti in tab.~\ref{tab:sock_data_types} con i rispettivi file di include in cui sono definiti; la struttura è invece -definita nell'include file \file{sys/socket.h}. +definita nell'include file \headfile{sys/socket.h}. \begin{table}[!htb] \centering @@ -406,21 +426,21 @@ definita nell'include file \file{sys/socket.h}. \multicolumn{1}{|c|}{\textbf{Header}} \\ \hline \hline - \type{int8\_t} & intero a 8 bit con segno & \file{sys/types.h}\\ - \type{uint8\_t} & intero a 8 bit senza segno & \file{sys/types.h}\\ - \type{int16\_t} & intero a 16 bit con segno & \file{sys/types.h}\\ - \type{uint16\_t} & intero a 16 bit senza segno& \file{sys/types.h}\\ - \type{int32\_t} & intero a 32 bit con segno & \file{sys/types.h}\\ - \type{uint32\_t} & intero a 32 bit senza segno& \file{sys/types.h}\\ + \type{int8\_t} & intero a 8 bit con segno & \headfile{sys/types.h}\\ + \type{uint8\_t} & intero a 8 bit senza segno & \headfile{sys/types.h}\\ + \type{int16\_t} & intero a 16 bit con segno & \headfile{sys/types.h}\\ + \type{uint16\_t} & intero a 16 bit senza segno& \headfile{sys/types.h}\\ + \type{int32\_t} & intero a 32 bit con segno & \headfile{sys/types.h}\\ + \type{uint32\_t} & intero a 32 bit senza segno& \headfile{sys/types.h}\\ \hline - \type{sa\_family\_t} & famiglia degli indirizzi& \file{sys/socket.h}\\ + \type{sa\_family\_t} & famiglia degli indirizzi&\headfile{sys/socket.h}\\ \type{socklen\_t} & lunghezza (\type{uint32\_t}) dell'indirizzo di - un socket& \file{sys/socket.h}\\ + un socket& \headfile{sys/socket.h}\\ \hline \type{in\_addr\_t} & indirizzo IPv4 (\type{uint32\_t}) & - \file{netinet/in.h}\\ + \headfile{netinet/in.h}\\ \type{in\_port\_t} & porta TCP o UDP (\type{uint16\_t})& - \file{netinet/in.h}\\ + \headfile{netinet/in.h}\\ \hline \end{tabular} \caption{Tipi di dati usati nelle strutture degli indirizzi, secondo quanto @@ -449,12 +469,12 @@ sarebbe più immediato per l'utente (che non dovrebbe più eseguire il casting), I socket di tipo \const{PF\_INET} vengono usati per la comunicazione attraverso internet; la struttura per gli indirizzi per un socket internet (se si usa IPv4) è definita come \struct{sockaddr\_in} nell'header file -\file{netinet/in.h} ed ha la forma mostrata in +\headfile{netinet/in.h} ed ha la forma mostrata in fig.~\ref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g. \begin{figure}[!htb] \footnotesize\centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/sockaddr_in.h} \end{minipage} \caption{La struttura \structd{sockaddr\_in} degli indirizzi dei socket @@ -474,7 +494,7 @@ Il membro \var{sin\_family} deve essere sempre impostato a \const{AF\_INET}, altrimenti si avrà un errore di \errcode{EINVAL}; il membro \var{sin\_port} specifica il \textsl{numero di porta}. I numeri di porta sotto il 1024 sono chiamati \textsl{riservati} in quanto utilizzati da servizi standard e -soltanto processi con i privilegi di amministratore (con user-ID effettivo +soltanto processi con i privilegi di amministratore (con \ids{UID} effettivo uguale a zero) o con la \itindex{capabilities} \textit{capability} \const{CAP\_NET\_BIND\_SERVICE} possono usare la funzione \func{bind} (che vedremo in sez.~\ref{sec:TCP_func_bind}) su queste porte. @@ -482,14 +502,14 @@ vedremo in sez.~\ref{sec:TCP_func_bind}) su queste porte. Il membro \var{sin\_addr} contiene un indirizzo internet, e viene acceduto sia 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 +direttamente come intero. In \headfile{netinet/in.h} vengono definite anche +alcune costanti che identificano alcuni indirizzi speciali, riportati in tab.~\ref{tab:TCP_ipv4_addr}, che rincontreremo 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è con i bit ordinati in formato \textit{big endian} (vedi -sez.~\ref{sec:sock_endianess}), questo comporta la necessità di usare apposite +sez.~\ref{sec:sock_endianness}), questo comporta la necessità di usare apposite funzioni di conversione per mantenere la portabilità del codice (vedi sez.~\ref{sec:sock_addr_func} per i dettagli del problema e le relative soluzioni). @@ -501,12 +521,12 @@ soluzioni). Essendo IPv6 un'estensione di IPv4, i socket di tipo \const{PF\_INET6} sono sostanzialmente identici ai precedenti; la parte in cui si trovano praticamente tutte le differenze fra i due socket è quella della struttura -degli indirizzi; la sua definizione, presa da \file{netinet/in.h}, è riportata -in fig.~\ref{fig:sock_sa_ipv6_struct}. +degli indirizzi; la sua definizione, presa da \headfile{netinet/in.h}, è +riportata in fig.~\ref{fig:sock_sa_ipv6_struct}. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/sockaddr_in6.h} \end{minipage} \caption{La struttura \structd{sockaddr\_in6} degli indirizzi dei socket @@ -547,11 +567,12 @@ fig.~\ref{fig:sock_sa_local_struct}. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/sockaddr_un.h} \end{minipage} \caption{La struttura \structd{sockaddr\_un} degli indirizzi dei socket - locali (detti anche \textit{unix domain}) definita in \file{sys/un.h}.} + locali (detti anche \textit{unix domain}) definita in + \headfile{sys/un.h}.} \label{fig:sock_sa_local_struct} \end{figure} @@ -560,9 +581,9 @@ il campo \var{sun\_path} deve specificare un indirizzo. Questo ha due forme; può essere un file (di tipo socket) nel filesystem o una stringa univoca (mantenuta in uno spazio di nomi astratto). Nel primo caso l'indirizzo viene specificato come una stringa (terminata da uno zero) corrispondente al -\itindex{pathname} \textit{pathname} del file; nel secondo invece -\var{sun\_path} inizia con uno zero e vengono usati come nome i restanti byte -come stringa, senza terminazione. +\textit{pathname} del file; nel secondo invece \var{sun\_path} inizia con uno +zero e vengono usati come nome i restanti byte come stringa, senza +terminazione. \subsection{La struttura degli indirizzi AppleTalk} @@ -586,11 +607,11 @@ per \param{protocol} è \const{ATPROTO\_DDP}. Gli indirizzi AppleTalk devono essere specificati tramite una struttura \struct{sockaddr\_atalk}, la cui definizione è riportata in fig.~\ref{fig:sock_sa_atalk_struct}; la struttura viene dichiarata includendo -il file \file{netatalk/at.h}. +il file \headfile{netatalk/at.h}. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/sockaddr_atalk.h} \end{minipage} \caption{La struttura \structd{sockaddr\_atalk} degli indirizzi dei socket @@ -604,7 +625,7 @@ inferiori a 129 sono usati per le \textsl{porte riservate}, e possono essere usati solo da processi con i privilegi di amministratore o con la \itindex{capabilities} \textit{capability} \const{CAP\_NET\_BIND\_SERVICE}. L'indirizzo remoto è specificato nella struttura \var{sat\_addr}, e deve -essere in \textit{network order} (vedi sez.~\ref{sec:sock_endianess}); esso è +essere in \textit{network order} (vedi sez.~\ref{sec:sock_endianness}); esso è composto da un parte di rete data dal campo \var{s\_net}, che può assumere il valore \const{AT\_ANYNET}, che indica una rete generica e vale anche per indicare la rete su cui si è, il singolo nodo è indicato da \var{s\_node}, e @@ -624,9 +645,8 @@ implementare dei protocolli in user space, agendo direttamente sul livello fisico. In genere comunque si preferisce usare la libreria \file{pcap},\footnote{la libreria è mantenuta insieme al comando \cmd{tcpdump}, informazioni e documentazione si possono trovare sul sito del - progetto \href{http://www.tcpdump.org/}{\textsf{http://www.tcpdump.org/}}.} -che assicura la portabilità su altre piattaforme, anche se con funzionalità -ridotte. + progetto \url{http://www.tcpdump.org/}.} che assicura la portabilità su +altre piattaforme, anche se con funzionalità ridotte. Questi socket possono essere di tipo \const{SOCK\_RAW} o \const{SOCK\_DGRAM}. Con socket di tipo \const{SOCK\_RAW} si può operare sul livello di @@ -655,7 +675,7 @@ simboliche definite nel file \file{linux/if\_ether.h}. Se si usa il valore speciale \const{ETH\_P\_ALL} passeranno sul \textit{packet socket} tutti i pacchetti, qualunque sia il loro protocollo di collegamento. Ovviamente l'uso di questi socket è una operazione privilegiata e può essere effettuati solo da -un processo con i privilegi di amministratore (user-ID effettivo nullo) o con +un processo con i privilegi di amministratore (\ids{UID} effettivo nullo) o con la \itindex{capabilities} \textit{capability} \const{CAP\_NET\_RAW}. Una volta aperto un \textit{packet socket}, tutti i pacchetti del protocollo @@ -665,7 +685,7 @@ occorre usare la funzione \func{bind} per agganciare il socket a quest'ultima. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{15cm} + \begin{minipage}[c]{\textwidth} \includestruct{listati/sockaddr_ll.h} \end{minipage} \caption{La struttura \structd{sockaddr\_ll} degli indirizzi dei @@ -752,8 +772,8 @@ può comportare la necessità di eseguire delle conversioni. \subsection{Le funzioni per il riordinamento} \label{sec:sock_func_ord} -Come già visto in sez.~\ref{sec:sock_endianess} il problema connesso -\itindex{endianess} all'\textit{endianess} è che quando si passano dei dati da +Come già visto in sez.~\ref{sec:sock_endianness} il problema connesso +\itindex{endianness} all'\textit{endianness} è che quando si passano dei dati da un tipo 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 byte in cui è suddiviso scambiati di posto. Per questo motivo si usano delle @@ -841,9 +861,10 @@ nell'indirizzo binario che viene memorizzato nell'opportuna struttura \struct{in\_addr} (si veda fig.~\ref{fig:sock_sa_ipv4_struct}) situata all'indirizzo dato dall'argomento \param{dest} (è espressa in questa forma in modo da poterla usare direttamente con il puntatore usato per passare la -struttura degli indirizzi). La funzione restituisce 0 in caso di successo e 1 -in caso di fallimento. Se usata con \param{dest} inizializzato a \val{NULL} -effettua la validazione dell'indirizzo. +struttura degli indirizzi). La funzione restituisce un valore diverso da zero +se l'indirizzo è valido e la conversione ha successo e 0 in caso contrario. +Se usata con \param{dest} inizializzato a \val{NULL} effettua la validazione +dell'indirizzo. L'ultima funzione, \func{inet\_ntoa}, converte il valore a 32 bit dell'indirizzo (espresso in \textit{network order}) restituendo il puntatore @@ -944,9 +965,9 @@ sez.~\ref{sec:IP_ipv6_notation} per IPv6. % LocalWords: pathname AppleTalk netatalk personal Apple ATPROTO atalk sat if % LocalWords: ANYNET node ANYNODE ATADDR BCAST pcap IEEE linux ether ETH ALL % LocalWords: sll ifindex ethernet halen MAC hatype ARP arp pkttype HOST recv -% LocalWords: OTHERHOST OUTGOING recvfrom recvmsg endianess little endtest Mac +% LocalWords: OTHERHOST OUTGOING recvfrom recvmsg endianness little endtest Mac % LocalWords: Intel Digital Motorola IBM VME PowerPC l'Intel xABCD ptr htonl -% LocalWords: all'endianess htons ntohl ntohs long hostlong hostshort netlong +% LocalWords: htons ntohl ntohs long hostlong hostshort netlong % LocalWords: sort netshort host inet aton ntoa dotted decimal const char src % LocalWords: strptr struct dest addrptr INADDR NULL pton ntop presentation af % LocalWords: numeric EAFNOSUPPORT size ENOSPC ENOAFSUPPORT ADDRSTRLEN ROUTE