From d429b57bfd2108e922838756d4909251065a41f4 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Thu, 16 Dec 2004 00:32:10 +0000 Subject: [PATCH] tre note sul POLL* e i socket piu getsockopt --- sockctrl.tex | 115 ++++++++++++++++++++++++++++++++++++++------------- tcpsock.tex | 10 +++-- 2 files changed, 94 insertions(+), 31 deletions(-) diff --git a/sockctrl.tex b/sockctrl.tex index 4b07f89..ee24c59 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -1850,7 +1850,7 @@ prototipo \funcdecl{int setsockopt(int sock, int level, int optname, const void *optval, socklen\_t optlen)} - + Imposta 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: @@ -1866,33 +1866,34 @@ prototipo } \end{functions} + Il primo argomento della funzione, \param{sock}, indica il socket su cui si -intende operare; il secondo argomento, \param{level} indica invece il livello -a cui si intende impostare l'opzione. Come abbiamo visto in -sez.~\ref{sec:net_protocols} infatti i protocolli di rete sono strutturati su -più livelli; pertanto anche le proprietà e le opzioni disponibili dipendono -dai protocolli usati dal socket sul quale si va ad agire, e saranno anche esse -differenziate a seconda del protocollo cui fanno riferimento. - - - - -Il valore di \param{level} seleziona allora il livello sul quale si va ad -intervenire e permette di usare le opzioni definite su quel livello. Esiste -poi il valore \const{SOL\_SOCKET} che indica un livello generico e cioè le -opzioni disponibili per qualunque tipo di socket. Per impostare le opzioni -relative alle funzionalità disponibili per socket che usano particolari -protocolli può utilizzare il valore numerico che identifica questi ultimi in -\file{/etc/protocols}, ma più comunemente si suano le apposite costanti -\texttt{SOL\_*} riportate in tab.~\ref{tab:sock_option_levels} dove si sono -riassunti i possibili valori 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 delle - analoghe \texttt{IPPROTO\_*} (citate anche da Stevens in \cite{UNP1}) che di - nuovo sono equivalenti ai numeri di protocollo di \file{/etc/protocols}; con +intende operare; per indicare l'opzione da impostare si devono usare i due +argomenti successivi, \param{level} e \param{optname}. Come abbiamo visto in +sez.~\ref{sec:net_protocols} i protocolli di rete sono strutturati su vari +livelli, ed l'interfaccia dei socket può usarne più di uno. Si avranno allora +diverse funzionalità e caratteristiche per ciascun protocollo usato da un +socket, e quindi saranno anche diverse le opzioni che di potranno impostare, a +seconda del \textsl{livello} (trasporto, rete, ecc.) su cui si va ad operare. + +Il valore di \param{level} seleziona allora il protocollo su cui vuole +intervenire, e permette di usare per \param{optname} i valori delle opzioni +che sono definite su quel protocollo. Esiste però anche il valore speciale +\const{SOL\_SOCKET} che indica un livello di base e cioè le opzioni +disponibili per qualunque tipo di socket. Per impostare le opzioni relative +alle funzionalità dei singoli protocolli si deve utilizzare il valore numerico +che identifica questi ultimi in \file{/etc/protocols}; più comunemente si +usano le apposite costanti \texttt{SOL\_*} riportate in +tab.~\ref{tab:sock_option_levels}, dove si sono riassunti i valori possibili +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 \file{/etc/protocols}, con una eccesione specifica, che è quella del protocollo ICMP, per la quale non - esista una costante, dato poi che il suo valore, 1, è anche quello che viene - assegnato a \const{SOL\_SOCKET}.} + esista una costante, il che è comprensibile dato che il suo valore, 1, è + quello che viene assegnato a \const{SOL\_SOCKET}.} + \begin{table}[!htb] \centering @@ -1914,14 +1915,72 @@ riassunti i possibili valori per l'argomento \param{level}.\footnote{la \label{tab:sock_option_levels} \end{table} +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 (e il tipo di dati varia a seconda dell'opzione), mentre l'ultimo +argomento \param{optlen},\footnote{questo argomento è in realtà sempre di tipo + \ctyp{int}, come era nelle \acr{libc4} e \acr{libc5}; l'uso di + \ctyp{socklen\_t} è stato introdotto da POSIX (valgono le stesse + considerazioni per l'uso di questo tipo di dato fatte in + sez.~\ref{sec:TCP_func_accept}) ed adottato dalle \acr{glibc}.} è la +dimensione in byte dei dati presenti all'indirizzo indicato da \param{optval}. + +La gran parte delle opzioni utilizzano per \param{optval} un valore intero, se +poi l'opzione esprime una condizione logica si deve usare particolare un +valore non nullo per abilitarla ed un valore nullo per disabilitarla. Se +invece l'opzione non prevede di dover ricevere nessun tipo di valore si deve +impostare \param{optval} a \const{NULL}. + +La seconda funzione usata per controllare le proprietà dei socket è +\func{getsockopt}, che serve a leggere i valori delle opzioni dd 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{errlist} + \item[\errcode{EBADF}] il file descriptor \param{sock} non è valido. + \item[\errcode{EFAULT}] l'indirizzo \param{optval} o quello di + \param{optlen} non è valido. + \item[\errcode{ENOPROTOOPT}] l'opzione scelta non esiste per il livello + indicato. + \item[\errcode{ENOTSOCK}] il file descriptor \param{sock} non corrisponde ad + un socket. + \end{errlist} +} +\end{functions} + +I primi tre argomenti sono identici ed hanno lo stesso significato di quelli +di \func{setsockopt}, mentre \param{optval} in questo caso indica l'indirizzo +a cui andranno scritti i dati letti dal socket, e \param{optlen} è usata come +\textit{value result argument} per indicare la lunghezza del buffer allocato +per \param{optval} e per ricevere indietro la dimensione effettiva dei dati +scritti su di esso. \subsection{Le opzioni generiche} \label{sec:sock_generic_options} Anche se ciascun tipo di socket presenta una serie di caratteristiche -particolari, gestite attraverso delle opzioni specifiche, ma esiste un insieme -generico di opzioni che possono applicarsi a qualunque tipo di socket. +particolari, gestite attraverso delle opzioni specifiche, esiste un insieme +generico di opzioni che possono applicarsi a qualunque tipo di +socket.\footnote{una descrizione di queste opzioni è generalmente disponibile + nella quarta sezione delle pagine di manuale con \texttt{man 4 socket}.} +Come detto in tal caso il livello da scegliere è \const{SOL\_SOCKET} + + + +In generale il valore di \param{optname} viene passato invariato al + + + + + \section{Altre funzioni di controllo} diff --git a/tcpsock.tex b/tcpsock.tex index cec4ca8..ad5e205 100644 --- a/tcpsock.tex +++ b/tcpsock.tex @@ -3400,9 +3400,9 @@ condizioni della rete. Inoltre deve essere specificato come viene classificato il traffico nella suddivisione fra dati normali e prioritari. In generale pertanto: \begin{itemize} -\item i dati trasmessi su un socket vengono considerati traffico normale, - pertanto vengono rilevati da una selezione con \const{POLLIN} o - \const{POLLRDNORM}. +\item i dati inviati su un socket vengono considerati traffico normale, + pertanto vengono rilevati alla loro ricezione sull'altro capo da una + selezione effettuata con \const{POLLIN} o \const{POLLRDNORM}; \item i dati \textit{out-of-band} su un socket TCP vengono considerati traffico prioritario e vengono rilevati da una condizione \const{POLLIN}, \const{POLLPRI} o \const{POLLRDBAND}. @@ -3410,6 +3410,10 @@ pertanto: viene considerato traffico normale, pertanto viene rilevato da una condizione \const{POLLIN} o \const{POLLRDNORM}, ma una conseguente chiamata a \func{read} restituirà 0. +\item la disponibilità di spazio sul socket per la scrittura di dati viene + segnalata con una condizione \const{POLLOUT}. +\item quando uno dei due capi del socket chiude un suo lato della connessione + con \func{shutdown} si riceve una condizione di \const{POLLHUP}. \item la presenza di un errore sul socket (sia dovuta ad un segmento RST che a timeout) viene considerata traffico normale, ma viene segnalata anche dalla condizione \const{POLLERR}. -- 2.30.2