X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=elemtcp.tex;h=964dd4f16f5cc1c0539b9338093392ae75c5905a;hp=499bcf6a840be8bd73238e7b070dd2d3dc483c27;hb=de41308ec9349b36a117358295dacf7cb0bd0877;hpb=fadbc082a6f07263bc3bdccfbba52d1c9b6d9521 diff --git a/elemtcp.tex b/elemtcp.tex index 499bcf6..964dd4f 100644 --- a/elemtcp.tex +++ b/elemtcp.tex @@ -44,7 +44,7 @@ creazione di una connessione \func{connect}, attraverso un procedimento che viene chiamato \textsl{apertura attiva}, dall'inglese \textit{active open}. La chiamata di \func{connect} blocca il processo e causa l'invio da parte del client di un - segmento SYN\footnote{Si ricordi che il segmento è l'unità elementare di + segmento SYN,\footnote{Si ricordi che il segmento è l'unità elementare di dati trasmessa dal protocollo TCP al livello superiore; tutti i segmenti hanno un header che contiene le informazioni che servono allo \textit{stack TCP} (così viene di solito chiamata la parte del kernel che @@ -52,7 +52,7 @@ creazione di una connessione ci sono una serie di flag usati per gestire la connessione, come SYN, ACK, URG, FIN, alcuni di essi, come SYN (che sta per \textit{syncronize}) corrispondono a funzioni particolari del protocollo e danno il nome al - segmento, (per maggiori dettagli vedere \capref{cha:tcp_protocol})}, in + segmento, (per maggiori dettagli vedere \capref{cha:tcp_protocol}).} in sostanza viene inviato al server un pacchetto IP che contiene solo gli header IP e TCP (con il numero di sequenza iniziale e il flag SYN) e le opzioni di TCP. @@ -60,8 +60,8 @@ creazione di una connessione \item il server deve dare ricevuto (l'\textit{acknowledge}) del SYN del client, inoltre anche il server deve inviare il suo SYN al client (e trasmettere il suo numero di sequenza iniziale) questo viene fatto - ritrasmettendo un singolo segmento in cui entrambi i flag SYN ACK e sono - settati. + ritrasmettendo un singolo segmento in cui sono impostati entrambi i flag SYN + ACK. \item una volta che il client ha ricevuto l'acknowledge dal server la funzione \func{connect} ritorna, l'ultimo passo è dare dare il ricevuto del SYN del @@ -85,7 +85,7 @@ la connessione. \begin{figure}[htb] \centering - \includegraphics[width=10cm]{img/three_way_handshake.eps} + \includegraphics[width=10cm]{img/three_way_handshake} \caption{Il \textit{three way handshake} del TCP} \label{fig:TCPel_TWH} \end{figure} @@ -100,7 +100,7 @@ segmento. Il numero di sequenza di ciascun segmento viene calcolato a partire da un \textsl{numero di sequenza iniziale} generato in maniera casuale del kernel all'inizio della connessione e trasmesso con il SYN; l'acknowledgement di -ciascun segmento viene effettuato dall'altro capo della connessione settando +ciascun segmento viene effettuato dall'altro capo della connessione impostando il flag ACK e restituendo nell'apposito campo dell'header un \textit{acknowledge number}) pari al numero di sequenza che il ricevente si aspetta di ricevere con il pacchetto successivo; dato che il primo pacchetto @@ -128,20 +128,20 @@ regolare la connessione. Normalmente vengono usate le seguenti opzioni: \textsl{finestra annunciata} (\textit{advertized window}) con la quale ciascun capo della comunicazione dichiara quanto spazio disponibile ha in memoria per i dati. Questo è un numero a 16 bit dell'header, che così può - indicare un massimo di 65535 bytes (anche se Linux usa come massimo 32767 - per evitare problemi con alcuni stack bacati che usano l'aritmetica con - segno per implementare lo stack TCP); ma alcuni tipi di connessione come - quelle ad alta velocità (sopra i 45Mbits/sec) e quelle che hanno grandi - ritardi nel cammino dei pacchetti (come i satelliti) richiedono una finestra - più grande per poter ottenere il massimo dalla trasmissione, per questo - esiste questa opzione che indica un fattore di scala da applicare al valore - della finestra annunciata\footnote{essendo una nuova opzione per garantire - la compatibilità con delle vecchie implementazioni del protocollo la - procedura che la attiva prevede come negoziazione che l'altro capo della - connessione riconosca esplicitamente l'opzione inserendola anche lui nel - suo SYN di risposta dell'apertura della connessione} per la connessione - corrente (espresso come numero di bit cui shiftare a sinistra il valore - della finestra annunciata inserito nel pacchetto). + indicare un massimo di 65535 byte (anche se Linux usa come massimo 32767 per + evitare problemi con alcuni stack bacati che usano l'aritmetica con segno + per implementare lo stack TCP); ma alcuni tipi di connessione come quelle ad + alta velocità (sopra i 45Mbits/sec) e quelle che hanno grandi ritardi nel + cammino dei pacchetti (come i satelliti) richiedono una finestra più grande + per poter ottenere il massimo dalla trasmissione, per questo esiste questa + opzione che indica un fattore di scala da applicare al valore della finestra + annunciata\footnote{essendo una nuova opzione per garantire la compatibilità + con delle vecchie implementazioni del protocollo la procedura che la + attiva prevede come negoziazione che l'altro capo della connessione + riconosca esplicitamente l'opzione inserendola anche lui nel suo SYN di + risposta dell'apertura della connessione.} per la connessione corrente + (espresso come numero di bit cui shiftare a sinistra il valore della + finestra annunciata inserito nel pacchetto). \item \textit{timestamp option}, è anche questa una nuova opzione necessaria per le connessioni ad alta velocità per evitare possibili corruzioni di dati @@ -197,7 +197,7 @@ stabilisce la connessione. \begin{figure}[htb] \centering - \includegraphics[width=10cm]{img/tcp_close.eps} + \includegraphics[width=10cm]{img/tcp_close} \caption{La chiusura di una connessione TCP} \label{fig:TCPel_close} \end{figure} @@ -210,7 +210,7 @@ che si mantenga un flusso di dati dal capo della connessione che deve ancora eseguire la chiusura passiva a quello che sta eseguendo la chiusura attiva. Nella sequenza indicata i dati verrebbero persi, dato che si è chiuso il socket dal lato che esegue la chiusura attiva; esistono tuttavia situazioni in -cui si vuole poter sfuttare questa possibilità, usando una procedura che è +cui si vuole poter sfruttare questa possibilità, usando una procedura che è chiamata \textit{half-close}; torneremo su questo aspetto e su come utilizzarlo più avanti, quando parleremo della funzione \func{shutdown}. @@ -269,18 +269,18 @@ ad assumere per i due lati, server e client. \begin{figure}[htb] \centering - \includegraphics[width=9cm]{img/tcp_connection.eps} + \includegraphics[width=9cm]{img/tcp_connection} \caption{Schema dello scambio di pacchetti per un esempio di connessione} \label{fig:TPCel_conn_example} \end{figure} La connessione viene iniziata dal client che annuncia un MSS di 1460 (un -valore tipico per IPv4 su ethernet) con Linux, il server risponde con lo +valore tipico per IPv4 su Ethernet) con Linux, il server risponde con lo stesso valore (ma potrebbe essere anche un valore diverso). Una volta che la connessione è stabilita il client scrive al server una richiesta (che assumiamo stare in un singolo segmento, cioè essere minore dei -1460 bytes annunciati dal server), quest'ultimo riceve la richiesta e +1460 byte annunciati dal server), quest'ultimo riceve la richiesta e restituisce una risposta (che di nuovo supponiamo stare in un singolo segmento). Si noti che l'acknowledge della richiesta è mandato insieme alla risposta, questo viene chiamato \textit{piggybacking} ed avviene tutte le @@ -476,7 +476,7 @@ disposizione del kernel per gestire le relative tabelle. \begin{figure}[!htb] \centering - \includegraphics[width=10cm]{img/port_alloc.eps} + \includegraphics[width=10cm]{img/port_alloc} \caption{Allocazione dei numeri di porta} \label{fig:TCPel_port_alloc} \end{figure} @@ -640,17 +640,17 @@ ci si porr a \func{socket}, mentre il secondo e terzo argomento sono rispettivamente l'indirizzo (locale) del socket e la dimensione della struttura che lo contiene, secondo quanto già trattato in \secref{sec:sock_sockaddr}. - - La funzione restituisce zero in caso di successo e -1 per un errore; in caso - di errore la variabile \var{errno} viene settata secondo i seguenti - codici di errore: + + \bodydesc{La funzione restituisce zero in caso di successo e -1 per un + errore; in caso di errore la variabile \var{errno} viene impostata secondo + i seguenti codici di errore: \begin{errlist} - \item \macro{EBADF} il file descriptor non è valido. - \item \macro{EINVAL} il socket ha già un indirizzo assegnato. - \item \macro{ENOTSOCK} il file descriptor non è associato ad un socket. - \item \macro{EACCESS} si è cercato di usare una porta riservata senza + \item[\macro{EBADF}] il file descriptor non è valido. + \item[\macro{EINVAL}] il socket ha già un indirizzo assegnato. + \item[\macro{ENOTSOCK}] il file descriptor non è associato ad un socket. + \item[\macro{EACCESS}] si è cercato di usare una porta riservata senza sufficienti privilegi. - \end{errlist} + \end{errlist}} \end{prototype} Con il TCP la chiamata \func{bind} permette di specificare l'indirizzo, la @@ -662,7 +662,7 @@ per il server\footnote{un'eccezione a tutto ci In questo caso viene fatta assegnare dal kernel una porta effimera che poi viene registrata presso il \textit{portmapper}; quest'ultimo è un altro demone che deve essere contattato dai client per ottenere la porta effimera - su cui si trova il server} che in genere viene identificato dalla porta su + su cui si trova il server.} che in genere viene identificato dalla porta su cui risponde. Con \func{bind} si può assegnare un IP specifico ad un socket, purché questo @@ -686,7 +686,7 @@ un'assegnazione immediata del tipo: \footnotesize \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} - serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ + serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */ \end{lstlisting} \normalsize @@ -703,12 +703,13 @@ consente l'uso di una struttura costante come operando a destra in una assegnazione. Per questo nell'header \file{netinet/in.h} è definita una variabile -\type{in6addr\_any} (dichiarata come \type{extern}, ed inizializzata dal +\type{in6addr\_any} (dichiarata come \ctyp{extern}, ed inizializzata dal sistema al valore \macro{IN6ADRR\_ANY\_INIT}) che permette di effettuare una assegnazione del tipo: + \footnotesize \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} - serv_add.sin6_addr = in6addr_any; /* connect from anywhere */ + serv_add.sin6_addr = in6addr_any; /* connect from anywhere */ \end{lstlisting} \normalsize @@ -725,30 +726,30 @@ connessione con un server TCP, il prototipo della funzione a \func{socket}, mentre il secondo e terzo argomento sono rispettivamente l'indirizzo e la dimensione della struttura che contiene l'indirizzo del socket, già descritta in \secref{sec:sock_sockaddr}. - - La funzione restituisce zero in caso di successo e -1 per un errore, in caso - di errore la variabile \var{errno} viene settata secondo i seguenti - codici di errore: + + \bodydesc{La funzione restituisce zero in caso di successo e -1 per un + errore, in caso di errore la variabile \var{errno} viene impostata secondo + i seguenti codici di errore: \begin{errlist} - \item \macro{EISCONN} il socket è già connesso. - \item \macro{ECONNREFUSED} non c'è nessuno in ascolto sull'indirizzo remoto. - \item \macro{ETIMEDOUT} si è avuto timeout durante il tentativo di + \item[\macro{ECONNREFUSED}] non c'è nessuno in ascolto sull'indirizzo remoto. + \item[\macro{ETIMEDOUT}] si è avuto timeout durante il tentativo di connessione. - \item \macro{ENETUNREACH} la rete non è raggiungibile. - \item \macro{EADDRINUSE} l'indirizzo locale è in uso. - \item \macro{EINPROGRESS} il socket è non bloccante e la connessione non - può essere conclusa immediatamente. - \item \macro{EALREADY} il socket è non bloccante e un tentativo precedente - di connessione non si è ancora concluso. - \item \macro{EAGAIN} non ci sono più porte locali libere. - \item \macro{EAFNOSUPPORT} l'indirizzo non ha una famiglia di indirizzi + \item[\macro{ENETUNREACH}] la rete non è raggiungibile. + \item[\macro{EINPROGRESS}] il socket è non bloccante (vedi + \secref{sec:file_noblocking}) e la connessione non può essere conclusa + immediatamente. + \item[\macro{EALREADY}] il socket è non bloccante (vedi + \secref{sec:file_noblocking}) e un tentativo precedente di connessione non + si è ancora concluso. + \item[\macro{EAGAIN}] non ci sono più porte locali libere. + \item[\macro{EAFNOSUPPORT}] l'indirizzo non ha una famiglia di indirizzi corretta nel relativo campo. - \item \macro{EACCESS, EPERM} si è tentato di eseguire una connessione ad un + \item[\macro{EACCESS, EPERM}] si è tentato di eseguire una connessione ad un indirizzo broadcast senza che il socket fosse stato abilitato per il broadcast. \end{errlist} altri errori possibili sono: \macro{EFAULT}, \macro{EBADF}, - \macro{ENOTSOCK}. + \macro{ENOTSOCK}, \macro{EISCONN} e \macro{EADDRINUSE}.} \end{prototype} La struttura dell'indirizzo deve essere inizializzata con l'indirizzo IP e il @@ -770,11 +771,11 @@ seguenti: invece ripete l'emissione del SYN ad intervalli di 30 secondi per un numero di volte che può essere stabilito dall'utente sia con una opportuna \func{sysctl} che attraverso il filesystem \file{/proc} scrivendo il valore - voluto in \file{/proc/sys/net/ipv4/tcp\_syn\_retries}. Il valore di default + voluto in \file{/proc/sys/net/ipv4/tcp\_syn\_retries}. Il valore predefinito per la ripetizione dell'invio è di 5 volte, che comporta un timeout dopo circa 180 secondi. % -% Le informazioni su tutte le opzioni settabili via /proc stanno in +% Le informazioni su tutte le opzioni impostabili via /proc stanno in % Linux/Documentation/networking/ip-sysctl.txt % \item Il client riceve come risposta al SYN un RST significa che non c'è @@ -822,22 +823,22 @@ sostanza l'effetto della funzione \texttt{CLOSED} a quello \texttt{LISTEN}. In genere si chiama la funzione in un server dopo le chiamate a \func{socket} e \func{bind} e prima della chiamata ad \func{accept}. Il prototipo della funzione come definito dalla -man page è: +pagina di manuale è: \begin{prototype}{sys/socket.h}{int listen(int sockfd, int backlog)} La funzione pone il socket specificato da \var{sockfd} in modalità passiva e predispone una coda per le connessioni in arrivo di lunghezza pari a \var{backlog}. La funzione si può applicare solo a socket di tipo \macro{SOCK\_STREAM} o \macro{SOCK\_SEQPACKET}. - - La funzione restituisce 0 in caso di successo e -1 in caso di errore. I - codici di errore restituiti in \var{errno} sono i seguenti: + + \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore. I codici di errore restituiti in \var{errno} sono i seguenti: \begin{errlist} - \item \macro{EBADF} l'argomento \var{sockfd} non è un file descriptor + \item[\macro{EBADF}] l'argomento \var{sockfd} non è un file descriptor valido. - \item \macro{ENOTSOCK} l'argomento \var{sockfd} non è un socket. - \item \macro{EOPNOTSUPP} il socket è di un tipo che non supporta questa + \item[\macro{ENOTSOCK}] l'argomento \var{sockfd} non è un socket. + \item[\macro{EOPNOTSUPP}] il socket è di un tipo che non supporta questa operazione. - \end{errlist} + \end{errlist}} \end{prototype} @@ -878,11 +879,11 @@ dette code. Stevens riporta che BSD ha sempre applicato un fattore di 1.5 al valore, e provvede una tabella con i risultati ottenuti con vari kernel, compreso Linux 2.0, che mostrano le differenze fra diverse implementazioni. -In Linux il significato di questo valore è cambiato a partire dal kernel -2.2 per prevenire l'attacco chiamato \textit{syn flood}. Questo si basa +In Linux il significato di questo valore è cambiato a partire dal kernel 2.2 +per prevenire l'attacco chiamato \textit{syn flood}. Questo si basa sull'emissione da parte dell'attaccante di un grande numero di pacchetti SYN indirizzati verso una porta forgiati con indirizzo IP fasullo\footnote{con la - tecnica che viene detta \textit{ip spoofing}} così che i SYN$+$ACK vanno + tecnica che viene detta \textit{ip spoofing}.} così che i SYN$+$ACK vanno perduti e la coda delle connessioni incomplete viene saturata, impedendo di fatto ulteriori connessioni. @@ -936,39 +937,36 @@ effettuare la comunicazione. Se non ci sono connessioni completate il processo viene messo in attesa. Il prototipo della funzione è il seguente: \begin{prototype}{sys/socket.h} {int accept(int sockfd, struct sockaddr *addr, socklen\_t *addrlen)} - La funzione estrae la prima connessione relativa al socket \var{sockfd} + Estrae la prima connessione relativa al socket \var{sockfd} in attesa sulla coda delle connessioni complete, che associa ad nuovo socket con le stesse caratteristiche di \var{sockfd} (restituito dalla funzione stessa). Il socket originale non viene toccato. Nella struttura \var{addr} e nella variabile \var{addrlen} vengono restituiti indirizzo e relativa lunghezza del client che si è connesso. - La funzione restituisce un numero di socket descriptor positivo in caso di - successo e -1 in caso di errore, nel qual caso la variabile \var{errno} - viene settata ai seguenti valori: + \bodydesc{La funzione restituisce un numero di socket descriptor positivo in + caso di successo e -1 in caso di errore, nel qual caso la variabile + \var{errno} viene impostata ai seguenti valori: \begin{errlist} - \item \macro{EBADF} l'argomento \var{sockfd} non è un file descriptor + \item[\macro{EBADF}] l'argomento \var{sockfd} non è un file descriptor valido. - \item \macro{ENOTSOCK} l'argomento \var{sockfd} non è un socket. - \item \macro{EOPNOTSUPP} il socket è di un tipo che non supporta questa + \item[\macro{ENOTSOCK}] l'argomento \var{sockfd} non è un socket. + \item[\macro{EOPNOTSUPP}] il socket è di un tipo che non supporta questa operazione. - \item \macro{EAGAIN} o \macro{EWOULDBLOCK} il socket è stato settato come - non bloccante, e non ci sono connessioni in attesa di essere accettate. - \item \macro{EFAULT} l'argomento \var{addr} . - \item \macro{EPERM} Firewall rules forbid connection. - - \item \macro{ENOBUFS, ENOMEM} Not enough free memory. This often means - that the memory allocation is limited by the socket buffer limits, not by - the system memory. - - Inoltre possono essere restituiti gli errori di rete relativi al nuovo - socket come: \macro{EMFILE}, \macro{EINVAL}, \macro{ENOSR}, - \macro{ENOBUFS}, \macro{EPERM}, \macro{ECONNABORTED}, - \macro{ESOCKTNOSUPPORT}, \macro{EPROTONOSUPPORT}, \macro{ETIMEDOUT}, - \macro{ERESTARTSYS}. - + \item[\macro{EAGAIN} o \macro{EWOULDBLOCK}] il socket è stato impostato come + non bloccante (vedi \secref{sec:file_noblocking}), e non ci sono + connessioni in attesa di essere accettate. + \item[\macro{EPERM}] Le regole del firewall non consentono la connessione. + \item[\macro{ENOBUFS, ENOMEM}] questo spesso significa che l'allocazione + della memoria è limitata dai limiti sui buffer dei socket, non dalla + memoria di sistema. \end{errlist} + Inoltre possono essere restituiti gli errori di rete relativi al nuovo + socket come: \macro{EMFILE}, \macro{EINVAL}, \macro{ENOSR}, \macro{ENOBUFS}, + \macro{EFAULT}, \macro{EPERM}, \macro{ECONNABORTED}, + \macro{ESOCKTNOSUPPORT}, \macro{EPROTONOSUPPORT}, \macro{ETIMEDOUT}, + \macro{ERESTARTSYS}.} \end{prototype} La funzione può essere usata solo con socket che supportino la connessione @@ -977,8 +975,8 @@ La funzione pu esplicita della connessione, (attualmente in Linux solo DECnet ha questo comportamento), la funzione opera solo l'estrazione dalla coda delle connessioni, la conferma della connessione viene fatta implicitamente dalla -prima chiamata ad una \func{read} o una \func{write} mentre il rifiuto -della connessione viene fatto con la funzione \func{close}. +prima chiamata ad una \func{read} o una \func{write} mentre il rifiuto della +connessione viene fatto con la funzione \func{close}. È da chiarire che Linux presenta un comportamento diverso nella gestione degli errori rispetto ad altre implementazioni dei socket BSD, infatti la funzione @@ -993,7 +991,7 @@ I due argomenti \var{cliaddr} e \var{addrlen} (si noti che quest'ultimo l'indirizzo del client da cui proviene la connessione. Prima della chiamata \var{addrlen} deve essere inizializzato alle dimensioni della struttura il cui indirizzo è passato come argomento in \var{cliaddr}, al ritorno della -funzione \var{addrlen} conterrà il numero di bytes scritti dentro +funzione \var{addrlen} conterrà il numero di byte scritti dentro \var{cliaddr}. Se questa informazione non interessa basterà inizializzare a \macro{NULL} detti puntatori. @@ -1001,14 +999,14 @@ Se la funzione ha successo restituisce il descrittore di un nuovo socket creato dal kernel (detto \textit{connected socket}) a cui viene associata la prima connessione completa (estratta dalla relativa coda, vedi \secref{sec:TCPel_func_listen}) che il client TCP ha effettuato verso il -socket \var{sockfd}. Quest'ultimo (detto \textit{listening socket}) è -quello creato all'inizio e messo in ascolto con \func{listen}, e non viene -toccato dalla funzione. -Se non ci sono connessioni pendenti da accettare la funzione mette in attesa -il processo\footnote{a meno che non si sia settato il socket per essere - non-bloccante, nel qual caso ritorna con l'errore \func{EAGAIN}, - torneremo su questa modalità di operazione in \secref{sec:xxx_sock_noblock}} -fintanto che non ne arriva una. +socket \var{sockfd}. Quest'ultimo (detto \textit{listening socket}) è quello +creato all'inizio e messo in ascolto con \func{listen}, e non viene toccato +dalla funzione. Se non ci sono connessioni pendenti da accettare la funzione +mette in attesa il processo\footnote{a meno che non si sia imopstato il socket + per essere non bloccante (vedi \secref{sec:file_noblocking}), nel qual caso + ritorna con l'errore \macro{EAGAIN}. Torneremo su questa modalità di + operazione in \secref{sec:xxx_sock_noblock}.} fintanto che non ne arriva +una. Il meccanismo di funzionamento di \func{accept} è essenziale per capire il funzionamento di un server: in generale infatti c'è sempre un solo socket in @@ -1189,19 +1187,21 @@ certo socket; la prima restituisce l'indirizzo locale, la seconda quello remoto. \begin{prototype}{sys/socket.h} -{int getsockname(int sockfd, struct sockaddr * name, socklen\_t * namelen)} + {int getsockname(int sockfd, struct sockaddr * name, socklen\_t * namelen)} + Legge l'indirizzo locale del socket \param{sockfd} nella struttura + \param{name}. - La funzione restituisce 0 in caso di successo e -1 in caso di errore. I - codici di errore restituiti in \var{errno} sono i seguenti: +\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore. I codici di errore restituiti in \var{errno} sono i seguenti: \begin{errlist} - \item \macro{EBADF} l'argomento \var{sockfd} non è un file descriptor + \item[\macro{EBADF}] l'argomento \var{sockfd} non è un file descriptor valido. - \item \macro{ENOTSOCK} l'argomento \var{sockfd} non è un socket. - \item \macro{ENOBUFS} non ci sono risorse sufficienti nel sistema per + \item[\macro{ENOTSOCK}] l'argomento \var{sockfd} non è un socket. + \item[\macro{ENOBUFS}] non ci sono risorse sufficienti nel sistema per eseguire l'operazione. - \item \macro{EFAULT} l'argomento \var{name} punta al di fuori dello + \item[\macro{EFAULT}] l'argomento \var{name} punta al di fuori dello spazio di indirizzi del processo. - \end{errlist} + \end{errlist}} \end{prototype} La funzione \func{getsockname} si usa tutte le volte che si vuole avere @@ -1217,20 +1217,22 @@ chiamata dopo il completamento di una connessione sul socket restituito da quella connessione. \begin{prototype}{sys/socket.h} -{int getpeername(int sockfd, struct sockaddr * name, socklen\_t * namelen)} - - La funzione restituisce 0 in caso di successo e -1 in caso di errore. I - codici di errore restituiti in \var{errno} sono i seguenti: + {int getpeername(int sockfd, struct sockaddr * name, socklen\_t * namelen)} + Legge l'indirizzo remoto del socket \param{sockfd} nella struttura + \param{name}. + + \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore. I codici di errore restituiti in \var{errno} sono i seguenti: \begin{errlist} - \item \macro{EBADF} l'argomento \var{sockfd} non è un file descriptor + \item[\macro{EBADF}] l'argomento \var{sockfd} non è un file descriptor valido. - \item \macro{ENOTSOCK} l'argomento \var{sockfd} non è un socket. - \item \macro{ENOTCONN} il socket non è connesso. - \item \macro{ENOBUFS} non ci sono risorse sufficienti nel sistema per + \item[\macro{ENOTSOCK}] l'argomento \var{sockfd} non è un socket. + \item[\macro{ENOTCONN}] il socket non è connesso. + \item[\macro{ENOBUFS}] non ci sono risorse sufficienti nel sistema per eseguire l'operazione. - \item \macro{EFAULT} l'argomento \var{name} punta al di fuori dello + \item[\macro{EFAULT}] l'argomento \var{name} punta al di fuori dello spazio di indirizzi del processo. - \end{errlist} + \end{errlist}} \end{prototype} @@ -1246,7 +1248,7 @@ In generale per questo avviene quando il server invece di far gestire la connessione direttamente a un processo figlio, come nell'esempio precedente, lancia un opportuno programma per ciascuna connessione usando \func{exec} (questa ad -esempio è la modailità con cui opera il \textsl{super-server} \cmd{inetd} +esempio è la modalità con cui opera il \textsl{super-server} \cmd{inetd} che gestisce tutta una serie di servizi lanciando per ogni connessione l'opportuno server). @@ -1260,10 +1262,15 @@ connesso (\cmd{inetd} ad esempio fa sempre in modo che i file descriptor 0, 1 e 2 corrispondano al socket connesso) quest'ultimo potrà usare la funzione \func{getpeername} per determinare l'indirizzo remoto del client. -Infine è da chiarire (si legga la man page) che come per \func{accept} il -terzo parametro che è specificato dallo standard POSIX 1003.1g come di tipo -\type{socklen\_t *} in realtà deve sempre corrispondere ad un \type{int *} -come prima dello standard perché tutte le implementazioni dei socket BSD fanno -questa assunzione. +Infine è da chiarire (si legga la pagina di manuale) che, come per +\func{accept}, il terzo parametro, che è specificato dallo standard POSIX.1g +come di tipo \code{socklen\_t *} in realtà deve sempre corrispondere ad un +\ctyp{int *} come prima dello standard perché tutte le implementazioni dei +socket BSD fanno questa assunzione. + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "gapil" +%%% End: