%% socket.tex
%%
-%% Copyright (C) 2000-2006 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2007 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",
%% license is included in the section entitled "GNU Free Documentation
%% License".
%%
+
\chapter{Introduzione ai socket}
\label{cha:socket_intro}
Iniziamo con una descrizione essenziale di cosa sono i \textit{socket} e di
quali sono i concetti fondamentali da tenere presente quando si ha a che fare
con essi.
-\index{socket|(}
+\index{socket!definizione|(}
\subsection{I \textit{socket}}
\label{sec:sock_socket_def}
dovranno essere opportunamente trattati, ecc.
-\section{La creazione di un \textit{socket}}
+\section{La creazione di un socket}
\label{sec:sock_creation}
Come accennato l'interfaccia dei socket è estremamente flessibile e permette
-1 in caso di fallimento, nel qual caso la variabile \var{errno} assumerà
i valori:
\begin{errlist}
- \item[\errcode{EPROTONOSUPPORT}] Il tipo di socket o il protocollo scelto non
- sono supportati nel dominio.
- \item[\errcode{ENFILE}] Il kernel non ha memoria sufficiente a creare una
+ \item[\errcode{EPROTONOSUPPORT}] il tipo di socket o il protocollo scelto
+ non sono supportati nel dominio.
+ \item[\errcode{ENFILE}] il kernel non ha memoria sufficiente a creare una
nuova struttura per il socket.
- \item[\errcode{EMFILE}] Si è ecceduta la tabella dei file.
- \item[\errcode{EACCES}] Non si hanno privilegi per creare un socket nel
+ \item[\errcode{EMFILE}] si è ecceduta la tabella dei file.
+ \item[\errcode{EACCES}] non si hanno privilegi per creare un socket nel
dominio o con il protocollo specificato.
- \item[\errcode{EINVAL}] Protocollo sconosciuto o dominio non disponibile.
- \item[\errcode{ENOBUFS}] Non c'è sufficiente memoria per creare il socket
+ \item[\errcode{EINVAL}] protocollo sconosciuto o dominio non disponibile.
+ \item[\errcode{ENOBUFS}] non c'è sufficiente memoria per creare il socket
(può essere anche \errval{ENOMEM}).
\end{errlist}
inoltre, a seconda del protocollo usato, potranno essere generati altri
a zero (con l'eccezione dei \textit{raw socket}).
Si noti che la creazione del socket si limita ad allocare le opportune
-strutture nel kernel (sostanzialmente una voce nella \textit{file table}) e
-non comporta nulla riguardo all'indicazione degli indirizzi remoti o locali
-attraverso i quali si vuole effettuare la comunicazione.
+strutture nel kernel (sostanzialmente una voce nella \itindex{file~table}
+\textit{file table}) e non comporta nulla riguardo all'indicazione degli
+indirizzi remoti o locali attraverso i quali si vuole effettuare la
+comunicazione.
-\subsection{Il dominio, o \textit{protocol family}}
+\subsection{Il dominio dei socket}
\label{sec:sock_domain}
Dati i tanti e diversi protocolli di comunicazione disponibili, esistono vari
chiamano \textsl{domini}. La scelta di un dominio equivale in sostanza alla
scelta di una famiglia di protocolli, e viene effettuata attraverso
l'argomento \param{domain} della funzione \func{socket}. Ciascun dominio ha un
-suo nome simbolico che convenzionalmente inizia con una costante che inizia
-per \texttt{PF\_}, iniziali di \textit{protocol family}, un altro nome con cui
-si indicano i domini.
+suo nome simbolico che convenzionalmente è indicato da una costante che inizia
+per \texttt{PF\_}, sigla che sta per \textit{protocol family}, altro nome con
+cui si indicano i domini.
A ciascun tipo di dominio corrisponde un analogo nome simbolico, anch'esso
associato ad una costante, che inizia invece per \texttt{AF\_} (da
\hline
\const{PF\_UNSPEC} & 0& Non specificato & \\
\const{PF\_LOCAL} & 1& Local communication & unix(7) \\
- \const{PF\_UNIX}, \const{PF\_FILE}&1& & \\
+ \const{PF\_UNIX}, \const{PF\_FILE}&1&Sinonimi di \const{PF\_LOCAL}& \\
\const{PF\_INET} & 2& IPv4 Internet protocols & ip(7) \\
\const{PF\_AX25} & 3& Amateur radio AX.25 protocol & \\
\const{PF\_IPX} & 4& IPX - Novell protocols & \\
\const{PF\_SECURITY} &14& Security callback pseudo AF & \\
\const{PF\_KEY} &15& PF\_KEY key management API & \\
\const{PF\_NETLINK} &16& Kernel user interface device & netlink(7) \\
+ \const{PF\_ROUTE} &16& Sinonimo di \const{PF\_NETLINK} emula BSD.&\\
\const{PF\_PACKET} &17& Low level packet interface & packet(7) \\
\const{PF\_ASH} &18& Ash & \\
\const{PF\_ECONET} &19& Acorn Econet & \\
\const{PF\_IRDA} &23& IRDA socket & \\
\const{PF\_PPPOX} &24& PPPoX socket & \\
\const{PF\_WANPIPE} &25& Wanpipe API socket & \\
+ \const{PF\_LLC} &26& Linux LLC & \\
\const{PF\_BLUETOOTH}&31& Bluetooth socket & \\
\hline
\end{tabular}
- \caption{Famiglie di protocolli definiti in Linux.}
+ \caption{Famiglie di protocolli definiti in Linux.}
\label{tab:net_pf_names}
\end{table}
+% TODO aggiungere PF_CAN, vedi http://lwn.net/Articles/253425, dal 2.6.25
+
L'idea alla base della distinzione fra questi due insiemi di costanti era che
una famiglia di protocolli potesse supportare vari tipi di indirizzi, per cui
il prefisso \texttt{PF\_} si sarebbe dovuto usare nella creazione dei socket e
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
-\itindex{capabilities}\textit{capability} \const{CAP\_NET\_RAW}.
+\itindex{capabilities} \textit{capability} \const{CAP\_NET\_RAW}.
-\subsection{Il tipo, o stile}
+\subsection{Il tipo di socket}
\label{sec:sock_type}
La scelta di un dominio non comporta però la scelta dello stile 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
-seguenti costanti:
+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.}
\begin{basedescript}{\desclabelwidth{2.9cm}\desclabelstyle{\nextlinelabel}}
\item[\const{SOCK\_STREAM}] Provvede un canale di trasmissione dati
altro socket. I dati vengono ricevuti e trasmessi come un flusso continuo di
byte (da cui il nome \textit{stream}) e possono essere letti in blocchi di
dimensioni qualunque. Può supportare la trasmissione dei cosiddetti dati
- \itindex{out-of-band} \textit{out-of-band} (vedi
+ urgenti (o \itindex{out-of-band} \textit{out-of-band}, vedi
sez.~\ref{sec:TCP_urgent_data}).
\item[\const{SOCK\_DGRAM}] Viene usato per trasmettere pacchetti di dati
(\textit{datagram}) di lunghezza massima prefissata, indirizzati
devono usarlo, è riservato all'uso di sistema.
\item[\const{SOCK\_RDM}] Provvede un canale di trasmissione di dati
affidabile, ma in cui non è garantito l'ordine di arrivo dei pacchetti.
-\item[\const{SOCK\_PACKET}] Obsoleto, non deve essere usato.
+\item[\const{SOCK\_PACKET}] Obsoleto, non deve essere più usato.\footnote{e
+ pertanto non ne parleremo ulteriormente.}
\end{basedescript}
Si tenga presente che non tutte le combinazioni fra una famiglia di protocolli
\hline
\hline
&\const{SOCK\_STREAM} &\const{SOCK\_DGRAM} &\const{SOCK\_RAW}&
- \const{SOCK\_PACKET}&\const{SOCK\_SEQPACKET} \\
+ \const{SOCK\_RDM}&\const{SOCK\_SEQPACKET} \\
\hline
- \const{PF\_UNIX} & si & si & & & \\
+ \const{PF\_LOCAL} & si & si & & & \\
\hline
+% \const{PF\_UNIX}&\multicolumn{5}{|l|}{sinonimo di \const{PF\_LOCAL}.}\\
+% \hline
\const{PF\_INET} & TCP & UDP & IPv4 & & \\
\hline
\const{PF\_INET6} & TCP & UDP & IPv6 & & \\
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
-uguale a zero) o con la \itindex{capabilities}\textit{capability}
+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.
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
+\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.
campo \var{sat\_port} specifica la porta che identifica i vari servizi. Valori
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}.
+\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 è
composto da un parte di rete data dal campo \var{s\_net}, che può assumere il
direttamente su un'interfaccia di rete, senza passare per le funzioni di
gestione dei protocolli di livello superiore. In questo modo è possibile
implementare dei protocolli in user space, agendo direttamente sul livello
-fisico. In genere comunque si preferisce usare la libreria \file{pcap}, che
-assicura la portabilità su altre piattaforme, anche se con funzionalità
+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.
Questi socket possono essere di tipo \const{SOCK\_RAW} o \const{SOCK\_DGRAM}.
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
-la \itindex{capabilities}\textit{capability} \const{CAP\_NET\_RAW}.
+la \itindex{capabilities} \textit{capability} \const{CAP\_NET\_RAW}.
Una volta aperto un \textit{packet socket}, tutti i pacchetti del protocollo
specificato passeranno attraverso di esso, qualunque sia l'interfaccia da cui
\itindex{broadcast} \textit{broadcast}, \const{PACKET\_MULTICAST} per un
pacchetto inviato ad un indirizzo fisico di \itindex{multicast}
\textit{multicast}, \const{PACKET\_OTHERHOST} per un pacchetto inviato ad
-un'altra stazione (e ricevuto su un'interfaccia in modo promiscuo),
-\const{PACKET\_OUTGOING} per un pacchetto originato dalla propria macchina che
-torna indietro sul socket.
+un'altra stazione (e ricevuto su un'interfaccia in \index{modo~promiscuo} modo
+promiscuo), \const{PACKET\_OUTGOING} per un pacchetto originato dalla propria
+macchina che torna indietro sul socket.
Si tenga presente infine che in fase di ricezione, anche se si richiede il
Per capire meglio il problema si consideri un intero a 32 bit scritto in una
locazione di memoria posta ad un certo indirizzo. Come illustrato in
-fig.~\ref{fig:sock_endianess} i singoli bit possono essere disposti un memoria
+fig.~\ref{fig:sock_endianess} i singoli bit possono essere disposti in memoria
in due modi: a partire dal più significativo o a partire dal meno
significativo. Così nel primo caso si troverà il byte che contiene i bit più
significativi all'indirizzo menzionato e il byte con i bit meno significativi
\subsection{Le funzioni per il riordinamento}
\label{sec:sock_func_ord}
-Il problema connesso all'endianess\itindex{endianess} è che quando si passano
+Il problema connesso \itindex{endianess} all'endianess è 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
dell'indirizzo (espresso in \textit{network order}) restituendo il puntatore
alla stringa che contiene l'espressione in formato dotted decimal. Si deve
tenere presente che la stringa risiede in memoria statica, per cui questa
-funzione non è rientrante.
+funzione non è \index{funzioni!rientranti} rientrante.
\subsection{Le funzioni \func{inet\_pton} e \func{inet\_ntop}}
\textit{dotted decimal} per IPv4 e quello descritto in
sez.~\ref{sec:IP_ipv6_notation} per IPv6.
-\index{socket|)}
-
+\index{socket!definizione|)}
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "gapil"
-%%% End:
-
% LocalWords: socket sez cap BSD SVr XTI Transport Interface TCP stream UDP PF
% LocalWords: datagram broadcast descriptor sys int domain type protocol errno
% LocalWords: EPROTONOSUPPORT ENFILE kernel EMFILE EACCES EINVAL ENOBUFS raw
% LocalWords: all'endianess 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
+% LocalWords: numeric EAFNOSUPPORT size ENOSPC ENOAFSUPPORT ADDRSTRLEN ROUTE
+% LocalWords: of tcpdump page
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: