From 0dbba49e4c91e077cef2599a2cc735950b61e437 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Tue, 4 Apr 2017 13:22:03 +0000 Subject: [PATCH] Modifiche rimaste indietro. --- listati/TCP_echo_fifth.c | 2 + sockctrl.tex | 138 ++++++++++++++++++++++----------------- 2 files changed, 79 insertions(+), 61 deletions(-) diff --git a/listati/TCP_echo_fifth.c b/listati/TCP_echo_fifth.c index d3e383c..021b263 100644 --- a/listati/TCP_echo_fifth.c +++ b/listati/TCP_echo_fifth.c @@ -8,8 +8,10 @@ int main(int argc, char *argv[]) ... /* call sockaddr to get a connected socket */ if ( (sock = sockconn(argv[optind], "echo", 6, SOCK_STREAM)) < 0) { + if (errno) perror("Socket creation error"); return 1; } + ... /* do read/write operations */ ClientEcho(stdin, sock); /* normal exit */ diff --git a/sockctrl.tex b/sockctrl.tex index 1b8ee7b..2e6f324 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -2020,27 +2020,30 @@ quale si voglia far ascoltare il server. \label{sec:sock_options} Benché dal punto di vista del loro uso come canali di trasmissione di dati i -socket vengano trattati allo stesso modo dei file, siano acceduti tramite i -file descriptor, e gestiti con le ordinarie funzioni di lettura e scrittura -dei file, l'interfaccia standard usata per la gestione dei file generici non è -comunque sufficiente a poterne controllare tutte le caratteristiche -specifiche, considerato poi che queste variano a seconda del tipo di socket (e -della relativa forma di comunicazione sottostante). +socket vengano trattati allo stesso modo dei file, acceduti tramite i file +descriptor, e gestiti con le ordinarie funzioni di lettura e scrittura dei +file, l'interfaccia standard usata per la gestione dei file generici non è +comunque sufficiente a controllare la moltitudine di caratteristiche +specifiche che li contraddistinguono, considerato tra l'altro che queste +possono essere completamente diverse fra loro a seconda del tipo di socket e +della relativa forma di comunicazione sottostante. In questa sezione vedremo allora quali sono le funzioni dedicate alla gestione -delle caratteristiche specifiche dei vari tipi di socket, le cosiddette -\textit{socket options}, ma soprattutto analizzaremo quali sono queste opzioni -e quali caretteristiche e comportamenti dei socket permettono di controllare. +delle caratteristiche specifiche dei vari tipi di socket, che vengono +raggruppate sotto il nome generico di ``\textit{socket options}'', ma +soprattutto analizzaremo quali sono queste opzioni e quali caretteristiche e +comportamenti dei socket permettono di controllare. \subsection{Le funzioni di gestione delle opzioni dei socket} \label{sec:sock_setsockopt} -Le varie caratteristiche dei socket possono essere gestite attraverso l'uso di -due funzioni generiche che permettono rispettivamente di impostarle e di -recuperarne il valore corrente. La prima di queste due funzioni, quella usata -per impostare le \textit{socket options}, è \funcd{setsockopt}, ed il suo -prototipo è: +La modalità principale con cui si possono gestire le caratteristiche dei +socket (ne vedremo delle ulteriori nelle prossime sezioni) è quella che passa +attraverso l'uso di due funzioni di sistema generiche che permettono +rispettivamente di impostarle e di recuperarne il valore corrente. La prima di +queste due funzioni, quella usata per impostare le \textit{socket options}, è +\funcd{setsockopt}, ed il suo prototipo è: \begin{funcproto}{ \fhead{sys/socket.h} @@ -2084,22 +2087,6 @@ dal socket. Infine \param{level} prevede anche il valore speciale \const{SOL\_SOCKET} usato per le opzioni generiche che sono disponibili per qualunque tipo di socket. -I valori usati per \param{level}, corrispondenti ad un dato protocollo usato -da un socket, sono quelli corrispondenti al valore numerico che identifica il -suddetto protocollo in \conffile{/etc/protocols}; dato che la leggibilità di un -programma non trarrebbe certo beneficio dall'uso diretto dei valori numerici, -più comunemente si indica il protocollo tramite le apposite costanti -\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels}, dove si sono -riassunti i valori che possono essere usati per l'argomento -\param{level}.\footnote{la notazione in questo caso è, purtroppo, abbastanza - confusa: infatti in Linux il valore si può impostare sia usando le costanti - \texttt{SOL\_*}, che le analoghe \texttt{IPPROTO\_*} (citate anche da - Stevens in \cite{UNP1}); entrambe hanno gli stessi valori che sono - equivalenti ai numeri di protocollo di \conffile{/etc/protocols}, con una - eccezione specifica, che è quella del protocollo ICMP, per la quale non - esista una costante, il che è comprensibile dato che il suo valore, 1, è - quello che viene assegnato a \const{SOL\_SOCKET}.} - \begin{table}[!htb] \centering \footnotesize @@ -2120,6 +2107,23 @@ riassunti i valori che possono essere usati per l'argomento \label{tab:sock_option_levels} \end{table} +I valori usati per \param{level}, corrispondenti ad un dato protocollo usato +da un socket, sono quelli corrispondenti al valore numerico che identifica il +suddetto protocollo in \conffile{/etc/protocols}; dato che la leggibilità di un +programma non trarrebbe certo beneficio dall'uso diretto dei valori numerici, +più comunemente si indica il protocollo tramite le apposite costanti +\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels}, dove si sono +riassunti i valori che possono essere usati per l'argomento +\param{level}. + +La notazione in questo caso è, purtroppo, abbastanza confusa: infatti in Linux +il valore si può impostare sia usando le costanti \texttt{SOL\_*}, che le +analoghe \texttt{IPPROTO\_*} (citate anche da Stevens in \cite{UNP1}); +entrambe hanno gli stessi valori che sono equivalenti ai numeri di protocollo +di \conffile{/etc/protocols}, con una eccezione specifica, che è quella del +protocollo ICMP, per la quale non esiste una costante, il che è comprensibile +dato che il suo valore, 1, è quello che viene assegnato a \const{SOL\_SOCKET}. + Il quarto argomento, \param{optval} è un puntatore ad una zona di memoria che contiene i dati che specificano il valore dell'opzione che si vuole passare al socket, mentre l'ultimo argomento \param{optlen},\footnote{questo argomento è @@ -2143,15 +2147,18 @@ di opzioni però usano dei tipi di dati peculiari, è questo il motivo per cui La seconda funzione usata per controllare le proprietà dei socket è \funcd{getsockopt}, che serve a leggere i valori delle opzioni dei socket ed a farsi restituire i dati relativi al loro funzionamento; il suo prototipo è: -\begin{functions} - \headdecl{sys/socket.h} - \headdecl{sys/types.h} - \funcdecl{int getsockopt(int s, int level, int optname, void *optval, - socklen\_t *optlen)} Legge le opzioni di un socket. - \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} assumerà i valori: +\begin{funcproto}{ +\fhead{sys/socket.h} +\fhead{sys/types.h} +\fdecl{int getsockopt(int s, int level, int optname, void *optval, + socklen\_t *optlen)} +\fdesc{Legge le opzioni di un socket.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EBADF}] il file descriptor \param{sock} non è valido. \item[\errcode{EFAULT}] l'indirizzo \param{optval} o quello di @@ -2162,7 +2169,7 @@ farsi restituire i dati relativi al loro funzionamento; il suo prototipo è: un socket. \end{errlist} } -\end{functions} +\end{funcproto} I primi tre argomenti sono identici ed hanno lo stesso significato di quelli di \func{setsockopt}, anche se non è detto che tutte le opzioni siano definite @@ -2199,10 +2206,36 @@ tab.~\ref{tab:sock_opt_socklevel}. \textbf{Descrizione}\\ \hline \hline + \const{SO\_ACCEPTCONN}&$\bullet$& & &\texttt{int}& + Indica se il socket è in ascolto.\\ + \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$& &\texttt{char *}& + Lega il socket ad un dispositivo.\\ + \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Attiva o disattiva il \textit{broadcast}.\\ + \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Abilita la compatibilità con BSD.\\ + \const{SO\_DEBUG} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Abilita il debugging sul socket.\\ + \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Non invia attraverso un gateway.\\ + \const{SO\_ERROR} &$\bullet$& & &\texttt{int}& + Riceve e cancella gli errori pendenti.\\ \const{SO\_KEEPALIVE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& Controlla l'attività della connessione.\\ + \const{SO\_LINGER} &$\bullet$&$\bullet$& &\texttt{linger}& + Indugia nella chiusura con dati da spedire.\\ + \const{SO\_MARK} &$\bullet$&$\bullet$& &\texttt{int}& + Imposta un ``\textit{firewall mark}'' sul socket.\\ \const{SO\_OOBINLINE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& Lascia in linea i dati \textit{out-of-band}.\\ + \const{SO\_PASSCRED} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& + Abilita la ricezione di credenziali.\\ + \const{SO\_PEERCRED} &$\bullet$& & &\texttt{ucred}& + Restituisce le credenziali del processo remoto.\\ + \const{SO\_PRIORITY} &$\bullet$&$\bullet$& &\texttt{int}& + Imposta la priorità del socket.\\ + \const{SO\_PROTOCOL} &$\bullet$& & &\texttt{int}& + Ottiene il protocollo usato dal socket.\\ \const{SO\_RCVLOWAT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& Basso livello sul buffer di ricezione.\\ \const{SO\_SNDLOWAT} &$\bullet$&$\bullet$& &\texttt{int}& @@ -2211,36 +2244,14 @@ tab.~\ref{tab:sock_opt_socklevel}. Timeout in ricezione.\\ \const{SO\_SNDTIMEO} &$\bullet$&$\bullet$& &\texttt{timeval}& Timeout in trasmissione.\\ - \const{SO\_BSDCOMPAT}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Abilita la compatibilità con BSD.\\ - \const{SO\_PASSCRED} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Abilita la ricezione di credenziali.\\ - \const{SO\_PEERCRED} &$\bullet$& & &\texttt{ucred}& - Restituisce le credenziali del processo remoto.\\ - \const{SO\_BINDTODEVICE}&$\bullet$&$\bullet$& &\texttt{char *}& - Lega il socket ad un dispositivo.\\ - \const{SO\_DEBUG} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Abilita il debugging sul socket.\\ \const{SO\_REUSEADDR}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& Consente il riutilizzo di un indirizzo locale.\\ \const{SO\_TYPE} &$\bullet$& & &\texttt{int}& Restituisce il tipo di socket.\\ - \const{SO\_ACCEPTCONN}&$\bullet$& & &\texttt{int}& - Indica se il socket è in ascolto.\\ - \const{SO\_DONTROUTE}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Non invia attraverso un gateway.\\ - \const{SO\_BROADCAST}&$\bullet$&$\bullet$&$\bullet$&\texttt{int}& - Attiva o disattiva il \textit{broadcast}.\\ \const{SO\_SNDBUF} &$\bullet$&$\bullet$& &\texttt{int}& Imposta dimensione del buffer di trasmissione.\\ \const{SO\_RCVBUF} &$\bullet$&$\bullet$& &\texttt{int}& Imposta dimensione del buffer di ricezione.\\ - \const{SO\_LINGER} &$\bullet$&$\bullet$& &\texttt{linger}& - Indugia nella chiusura con dati da spedire.\\ - \const{SO\_PRIORITY} &$\bullet$&$\bullet$& &\texttt{int}& - Imposta la priorità del socket.\\ - \const{SO\_ERROR} &$\bullet$& & &\texttt{int}& - Riceve e cancella gli errori pendenti.\\ \hline \end{tabular} \caption{Le opzioni disponibili al livello \const{SOL\_SOCKET}.} @@ -2252,10 +2263,15 @@ tab.~\ref{tab:sock_opt_socklevel}. % TODO aggiungere e documentare SO_INCOMING_CPU, introdotta con il kernel 3.19, % vedi https://lwn.net/Articles/626150/ +% TODO documentare SO_MARK, cercare esempi e verificare il tipo di valore passato +% TODO documentare SO_PEEK_OFF +% TODO documentare SO_PROTOCOL + + La tabella elenca le costanti che identificano le singole opzioni da usare come valore per \param{optname}; le due colonne seguenti indicano per quali delle due funzioni (\func{getsockopt} o \func{setsockopt}) l'opzione è -disponibile, mentre la colonna successiva indica, quando di ha a che fare con +disponibile, mentre la colonna successiva indica, quando si ha a che fare con un valore di \param{optval} intero, se l'opzione è da considerare un numero o un valore logico. Si è inoltre riportato sulla quinta colonna il tipo di dato usato per \param{optval} ed una breve descrizione del significato delle -- 2.30.2