From d015e72d818c1632b0171cb6bea8c31018ff433e Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Thu, 14 Sep 2006 15:57:01 +0000 Subject: [PATCH] Materiale su {{{TCP_CONNECTION}}}. --- listati/tcp_info.h | 4 - netlayer.tex | 9 +- network.tex | 2 +- sockctrl.tex | 210 +++++++++++++++++++++++++++++++-------------- sources/TCP_echo.c | 28 +++++- 5 files changed, 178 insertions(+), 75 deletions(-) diff --git a/listati/tcp_info.h b/listati/tcp_info.h index db03af1..e99b290 100644 --- a/listati/tcp_info.h +++ b/listati/tcp_info.h @@ -7,24 +7,20 @@ struct tcp_info u_int8_t tcpi_backoff; u_int8_t tcpi_options; u_int8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; - u_int32_t tcpi_rto; u_int32_t tcpi_ato; u_int32_t tcpi_snd_mss; u_int32_t tcpi_rcv_mss; - u_int32_t tcpi_unacked; u_int32_t tcpi_sacked; u_int32_t tcpi_lost; u_int32_t tcpi_retrans; u_int32_t tcpi_fackets; - /* Times. */ u_int32_t tcpi_last_data_sent; u_int32_t tcpi_last_ack_sent; /* Not remembered, sorry. */ u_int32_t tcpi_last_data_recv; u_int32_t tcpi_last_ack_recv; - /* Metrics. */ u_int32_t tcpi_pmtu; u_int32_t tcpi_rcv_ssthresh; diff --git a/netlayer.tex b/netlayer.tex index 4fb7e1f..39eafed 100644 --- a/netlayer.tex +++ b/netlayer.tex @@ -535,10 +535,11 @@ quello di IPv6 sono le seguenti: frammentazione di pacchetti troppo grandi potrà essere gestita solo ai capi della comunicazione (usando un'apposita estensione vedi sez.~\ref{sec:IP_ipv6_extens}). -\item IPv6 richiede il supporto per il \textit{path MTU discovery} (cioè il - protocollo per la selezione della massima lunghezza del pacchetto); seppure - questo sia in teoria opzionale, senza di esso non sarà possibile inviare - pacchetti più larghi della dimensione minima (576 byte). +\item IPv6 richiede il supporto per il \itindex{Maximum~Transfer~Unit} + \textit{path MTU discovery} (cioè il protocollo per la selezione della + massima lunghezza del pacchetto); seppure questo sia in teoria opzionale, + senza di esso non sarà possibile inviare pacchetti più larghi della + dimensione minima (576 byte). \end{itemize} \subsection{Gli indirizzi di IPv6} diff --git a/network.tex b/network.tex index e7859a0..e5d7405 100644 --- a/network.tex +++ b/network.tex @@ -780,7 +780,6 @@ Il TCP usa sempre questo meccanismo, che per le implementazioni di IPv4 opzionale, mentre diventa obbligatorio per IPv6. Per IPv6 infatti, non potendo i router frammentare i pacchetti, è necessario, per poter comunicare, conoscere da subito il \textit{path MTU}. -\itindend{Maximum~Transfer~Unit} Infine TCP definisce una \itindex{Maximum~Segment~Size} \textit{Maximum Segment Size} (da qui in avanti abbreviata in MSS) che annuncia all'altro @@ -789,6 +788,7 @@ che pu impostato alla dimensione della MTU dell'interfaccia meno la lunghezza delle intestazioni di IP e TCP, in Linux il default, mantenuto nella costante \const{TCP\_MSS} è 512. +\itindend{Maximum~Transfer~Unit} %%% Local Variables: diff --git a/sockctrl.tex b/sockctrl.tex index 9841c0f..69894b3 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -2729,9 +2729,9 @@ sono definite in \file{netinet/ip.h}, ed accessibili includendo detto file. \const{IP\_RECVERR} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& abilita la gestione degli errori.\\ \const{IP\_MTU\_DISCOVER} &$\bullet$&$\bullet$& &\texttt{int}& - imposta il Path MTU Discovery.\\ + imposta il Path MTU \itindex{Maximum~Transfer~Unit} Discovery.\\ \const{IP\_MTU} &$\bullet$& & &\texttt{int}& - legge il valore attuale della MTU.\\ + legge il valore attuale della \itindex{Maximum~Transfer~Unit} MTU.\\ \const{IP\_ROUTER\_ALERT} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& imposta l'opzione \textit{IP router alert} sui pacchetti.\\ \const{IP\_MULTICAST\_TTL} &$\bullet$&$\bullet$& &\texttt{int}& @@ -2936,13 +2936,13 @@ sez.~\ref{sec:net_sendmsg}). esplicitamente connesso con \func{connect}. Ad esempio con i socket UDP si potrà ottenere una stima iniziale della - \textit{Path MTU} eseguendo prima una \func{connect} verso la destinazione, - e poi usando \func{getsockopt} con questa opzione. Si può anche avviare - esplicitamente il procedimento di scoperta inviando un pacchetto di grosse - dimensioni (che verrà scartato) e ripetendo l'invio coi dati aggiornati. Si - tenga infine conto che durante il procedimento i pacchetti iniziali possono - essere perduti, ed è compito dell'applicazione gestirne una eventuale - ritrasmissione. + \itindex{Maximum~Transfer~Unit} \textit{Path MTU} eseguendo prima una + \func{connect} verso la destinazione, e poi usando \func{getsockopt} con + questa opzione. Si può anche avviare esplicitamente il procedimento di + scoperta inviando un pacchetto di grosse dimensioni (che verrà scartato) e + ripetendo l'invio coi dati aggiornati. Si tenga infine conto che durante il + procedimento i pacchetti iniziali possono essere perduti, ed è compito + dell'applicazione gestirne una eventuale ritrasmissione. \itindend{Maximum~Transfer~Unit} @@ -3033,14 +3033,14 @@ precedenti opzioni di sez.~\ref{sec:sock_ipv4_options}.\footnote{in realt Il protocollo che supporta il maggior numero di opzioni è TCP; per poterle utilizzare occorre specificare \const{SOL\_TCP} (o l'equivalente \const{IPPROTO\_TCP}) come valore per l'argomento \param{level}. Si sono -riportate le varie opzioni disponibili in tab.~\ref{tab:sock_opt_tcp}, dove -sono elencate le rispettive costanti da utilizzare come valore per l'argomento -\param{optname}. Dette costanti e tutte le altre costanti e strutture -collegate all'uso delle opzioni TCP sono definite in \file{netinet/tcp.h}, ed -accessibili includendo detto file.\footnote{in realtà questo è il file usato - dalle librerie; la definizione delle opzioni effettivamente supportate da - Linux si trova nel file \texttt{linux/tcp.h}, dal quale si sono estratte le - costanti di tab.~\ref{tab:sock_opt_tcplevel}.} +riportate le varie opzioni disponibili in tab.~\ref{tab:sock_opt_tcplevel}, +dove sono elencate le rispettive costanti da utilizzare come valore per +l'argomento \param{optname}. Dette costanti e tutte le altre costanti e +strutture collegate all'uso delle opzioni TCP sono definite in +\file{netinet/tcp.h}, ed accessibili includendo detto file.\footnote{in realtà + questo è il file usato dalle librerie; la definizione delle opzioni + effettivamente supportate da Linux si trova nel file \texttt{linux/tcp.h}, + dal quale si sono estratte le costanti di tab.~\ref{tab:sock_opt_tcplevel}.} \begin{table}[!htb] \centering @@ -3076,8 +3076,8 @@ accessibili includendo detto file.\footnote{in realt restituisce informazioni sul socket.\\ \const{TCP\_QUICKACK} &$\bullet$&$\bullet$&$\bullet$&\texttt{int}& abilita la modalità \textit{quickack}.\\ - \const{TCP\_CONGESTION} &$\bullet$&$\bullet$&? &\texttt{?}& %??? - non ancora documentata.\\ + \const{TCP\_CONGESTION} &$\bullet$&$\bullet$& &\texttt{char *}& + imposta l'algoritmo per il controllo della congestione.\\ \hline \end{tabular} \caption{Le opzioni per i socket TCP disponibili al livello @@ -3089,7 +3089,8 @@ Le descrizioni delle varie opzioni riportate in tab.~\ref{tab:sock_opt_tcplevel} sono estremamente sintetiche ed indicative, la spiegazione del funzionamento delle singole opzioni con una maggiore quantità di dettagli è fornita nel seguente elenco: -\begin{basedescript}{\desclabelwidth{3.3cm}\desclabelstyle{\nextlinelabel}} +\begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}} + \item[\const{TCP\_NODELAY}] il protocollo TCP utilizza un meccanismo di bufferizzazione dei dati uscenti, per evitare la trasmissione di tanti @@ -3101,7 +3102,7 @@ quantit trasmessi; per evitare situazioni del genere è stato introdotto l'\textsl{algoritmo di Nagle}.} Questo meccanismo è controllato da un apposito algoritmo (detto \textsl{algoritmo di Nagle}, vedi - sez.\ref{sez:tcp_protocol_xxx}). Il comportamento normale del protocollo + sez.~\ref{sez:tcp_protocol_xxx}). Il comportamento normale del protocollo prevede che i dati siano accumulati fintanto che non si raggiunge una quantità considerata adeguata per eseguire la trasmissione di un singolo segmento. @@ -3127,13 +3128,13 @@ quantit kernel 2.5.71.} \item[\const{TCP\_MAXSEG}] con questa opzione si legge o si imposta il valore - della \itindex{Maximum~Segment~Size} MSS (vedi sez.~\ref{sec:net_lim_dim} e - sez.\ref{sez:tcp_protocol_xxx}) dei segmenti TCP uscenti. Se l'opzione è - impostata prima di stabilire la connessione, si cambia anche il valore della - \itindex{Maximum~Segment~Size} MSS annunciata all'altro capo della - connessione. Se si specificano valori maggiori della MTU questi verranno - ignorati, inoltre TCP imporrà anche i suoi limiti massimo e minimo per - questo valore. + della \itindex{Maximum~Segment~Size} MSS (\textit{Maximum~Segment~Size}, + vedi sez.~\ref{sec:net_lim_dim} e sez.~\ref{sez:tcp_protocol_xxx}) dei + segmenti TCP uscenti. Se l'opzione è impostata prima di stabilire la + connessione, si cambia anche il valore della \itindex{Maximum~Segment~Size} + MSS annunciata all'altro capo della connessione. Se si specificano valori + maggiori della \itindex{Maximum~Transfer~Unit} MTU questi verranno ignorati, + inoltre TCP imporrà anche i suoi limiti massimo e minimo per questo valore. \item[\const{TCP\_CORK}] questa opzione è il complemento naturale di \const{TCP\_NODELAY} e serve a gestire a livello applicativo la situazione @@ -3243,10 +3244,10 @@ quantit Allo stesso tempo il protocollo TCP prevede che sul lato del server la funzione \func{accept} ritorni dopo la ricezione dell'ACK finale, in tal caso quello che si fa usualmente è lanciare un nuovo processo per leggere i - successivi dati che si bloccherà su una \func{read} se questi non sono - disponibili, ma così si saranno impiegate delle risorse (per la creazione - del nuovo processo) che non saranno usate immediatamente. L'uso di - \const{TCP\_DEFER\_ACCEPT} consente di intervenire anche in questa + successivi dati, che si bloccherà su una \func{read} se questi non sono + disponibili; in questo modo si saranno impiegate delle risorse (per la + creazione del nuovo processo) che non vengono usate immediatamente. L'uso + di \const{TCP\_DEFER\_ACCEPT} consente di intervenire anche in questa situazione; quando la si invoca sul lato server (vale a dire su un socket in ascolto) l'opzione fa sì che \func{accept} ritorni soltanto quando sono presenti dei dati sul socket, e non alla ricezione dell'ACK conclusivo del @@ -3264,18 +3265,10 @@ quantit \item[\const{TCP\_WINDOW\_CLAMP}] con questa opzione si legge o si imposta alla dimensione specificata, in byte, il valore dichiarato della \itindex{advertised~window} \textit{advertised window} (vedi - sez.\ref{sez:tcp_protocol_xxx}). Il kernel impone comunque una dimensione + sez.~\ref{sez:tcp_protocol_xxx}). Il kernel impone comunque una dimensione minima pari a \texttt{SOCK\_MIN\_RCVBUF/2}. Questa opzione non deve essere utilizzata in codice che vuole essere portabile. -\item[\const{TCP\_INFO}] questa opzione, specifica di Linux, ma introdotta - anche in altri kernel (ad esempio FreeBSD) permette di controllare lo stato - di un socket TCP in user space. L'opzione restituisce in una speciale - struttura \struct{tcp\_info}, la cui definizione è riportata in - fig.~\ref{fig:tcp_info_struct}, tutta una serie di dati relativi al socket. - Anche questa opzione deve essere evitata se si vuole scrivere codice - portabile. - \begin{figure}[!htb] \footnotesize \centering \begin{minipage}[c]{15cm} @@ -3286,23 +3279,34 @@ quantit \label{fig:tcp_info_struct} \end{figure} -Con questa opzione diventa possibile ricevere una serie di informazioni -relative ad un socket TCP così da poter effettuare dei controlli senza dover -passare attraverso delle operazioni di lettura. Ad esempio si può verificare -se un socket è stato chiuso usando una funzione analoga a quella illustrata in -fig.~\ref{fig:is_closing}, in cui si utilizza il valore del campo -\var{tcpi\_state} di \struct{tcp\_info} per controllare lo stato del socket. +\item[\const{TCP\_INFO}] questa opzione, specifica di Linux, ma introdotta + anche in altri kernel (ad esempio FreeBSD) permette di controllare lo stato + interno di un socket TCP direttamente da un programma in user space. + L'opzione restituisce in una speciale struttura \struct{tcp\_info}, la cui + definizione è riportata in fig.~\ref{fig:tcp_info_struct}, tutta una serie + di dati che il kernel mantiene, relativi al socket. Anche questa opzione + deve essere evitata se si vuole scrivere codice portabile. + + Con questa opzione diventa possibile ricevere una serie di informazioni + relative ad un socket TCP così da poter effettuare dei controlli senza dover + passare attraverso delle operazioni di lettura. Ad esempio si può verificare + se un socket è stato chiuso usando una funzione analoga a quella illustrata + in fig.~\ref{fig:is_closing}, in cui si utilizza il valore del campo + \var{tcpi\_state} di \struct{tcp\_info} per controllare lo stato del socket. \begin{figure}[!htb] \footnotesize \centering \begin{minipage}[c]{15cm} - \includestruct{listati/tcp_info.h} + \includestruct{listati/is_closing.c} \end{minipage} \caption{Codice della funzione \texttt{is\_closing.c}, che controlla lo stato di un socket TCP per verificare se si sta chiudendo.} \label{fig:is_closing} \end{figure} +%Si noti come nell'esempio si sia ( + + \item[\const{TCP\_QUICKACK}] con questa opzione è possibile eseguire una forma di controllo sull'invio dei segmenti ACK all'interno di in flusso di dati su TCP. In genere questo invio viene gestito direttamente dal kernel, il @@ -3328,16 +3332,95 @@ fig.~\ref{fig:is_closing}, in cui si utilizza il valore del campo % TODO trattare con gli esempi di apache -\item[\const{TCP\_CONGESTION}] questa opzione permette di controllare gli - algoritmi usati dal protocollo TCP per la gestione della connessione. É - stata introdotta con il kernel 2.6.13, e non è documentata. +\item[\const{TCP\_CONGESTION}] questa opzione permette di impostare quale + algoritmo per il controllo della congestione\footnote{il controllo della + congestione è un meccanismo previsto dal protocollo TCP (vedi + sez.~\ref{sez:tcp_protocol_xxx}) per evitare di trasmettere inutilmente + dati quando una connessione è congestionata; un buon algoritmo è + fondamentale per il funzionamento del protocollo, dato che i pacchetti + persi andrebbero ritrasmessi, per cui inviare un pacchetto su una linea + congestionata potrebbe causare facilmente un peggioramento della + situazione.} utilizzare per il singolo socket. L'opzione è stata + introdotta con il kernel 2.6.13,\footnote{alla data di stesura di queste + note (Set. 2006) è pure scarsamente documentata, tanto che non è neanche + definita nelle intestazioni delle \acr{glibc} per cui occorre definirla a + mano al suo valore che è 13.} e prende come per \param{optval} il + puntatore ad un buffer contenente il nome dell'algoritmo di controllo che + si vuole usare. + + L'uso di un nome anziché di un valore numerico è dovuto al fatto che gli + algoritmi di controllo della congestione sono realizzati attraverso + altrettanti moduli del kernel, e possono pertanto essere attivati a + richiesta; il nome consente di caricare il rispettivo modulo e di introdurre + moduli aggiuntivi che implementino altri meccanismi. + + Per poter disporre di questa funzionalità occorre aver compilato il kernel + attivando l'opzione di configurazione generale + \texttt{TCP\_CONG\_ADVANCED},\footnote{disponibile come \textit{TCP: + advanced congestion control} nel menù \textit{Network->Networking + options}, che a sua volta renderà disponibile un ulteriore menù con gli + algoritmi presenti.} e poi abilitare i singoli moduli voluti con le varie + \texttt{TCP\_CONG\_*} presenti per i vari algoritmi disponibili; un elenco + di quelli attualmente supportati nella versione ufficiale del kernel è + riportato in tab.~\ref{tab:sock_tcp_congestion_algo}.\footnote{la lista è + presa dalla versione 2.6.17.} + + + Si tenga presente che prima della implementazione modulare alcuni di questi + algoritmi erano disponibili soltanto come caratteristiche generali del + sistema, attivabili per tutti i socket, questo è ancora possibile con la + \textit{sysctl} \texttt{tcp\_congestion\_control} (vedi + sez.~\ref{sec:sock_ipv4_sysctl}) che ha sostituito le precedenti + \textit{sysctl}.\footnote{riportate anche, alla data di stesura di queste + pagine (Set. 2006) nelle pagine di manuale, ma non più presenti.} + + \begin{table}[!htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|p{10cm}|} + \hline + \textbf{Nome}&\textbf{Configurazione}&\textbf{Riferimento} \\ + \hline + \hline + reno& -- &algoritmo tradizionale, usato in caso di assenza degli altri.\\ + \texttt{bic} &\texttt{TCP\_CONG\_BIC} & + \href{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm} + {\texttt{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}}.\\ + \texttt{cubic} &\texttt{TCP\_CONG\_CUBIC} & + \href{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm} + {\texttt{http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/index.htm}}.\\ + \texttt{highspeed}&\texttt{TCP\_CONG\_HSTCP} & + \href{http://www.icir.org/floyd/hstcp.html} + {\texttt{http://www.icir.org/floyd/hstcp.html}}.\\ + \texttt{htcp} &\texttt{TCP\_CONG\_HTCP} & + \href{http://www.hamilton.ie/net/htcp/} + {\texttt{http://www.hamilton.ie/net/htcp/}}.\\ + \texttt{hybla} &\texttt{TCP\_CONG\_HYBLA} & + \href{http://www.danielinux.net/projects.html} + {\texttt{http://www.danielinux.net/projects.html}}.\\ + \texttt{scalable}&\texttt{TCP\_CONG\_SCALABLE}& + \href{http://www.deneholme.net/tom/scalable/} + {\texttt{http://www.deneholme.net/tom/scalable/}}.\\ + \texttt{vegas} &\texttt{TCP\_CONG\_VEGAS} & + \href{http://www.cs.arizona.edu/protocols/} + {\texttt{http://www.cs.arizona.edu/protocols/}}.\\ + \texttt{westwood}&\texttt{TCP\_CONG\_WESTWOOD}& + \href{http://www.cs.ucla.edu/NRL/hpi/tcpw/} + {\texttt{http://www.cs.ucla.edu/NRL/hpi/tcpw/}}.\\ +% \texttt{}&\texttt{}& .\\ + \hline + \end{tabular} + \caption{Gli algoritmi per il controllo della congestione disponibili con + Linux con le relative opzioni di configurazione da attivare.} + \label{tab:sock_tcp_congestion_algo} + \end{table} \end{basedescript} Il protocollo UDP, anche per la sua maggiore semplicità, supporta un numero -ridotto di opzioni, riportate in tab.~\ref{tab:sock_opt_udp}; anche in questo -caso per poterle utilizzare occorrerà impostare l'opportuno valore per +ridotto di opzioni, riportate in tab.~\ref{tab:sock_opt_udplevel}; anche in +questo caso per poterle utilizzare occorrerà impostare l'opportuno valore per l'argomento \param{level}, che è \const{SOL\_UDP} (o l'equivalente \const{IPPROTO\_UDP}). Le costanti che identificano dette opzioni sono definite in \file{netinet/udp.h}, ed accessibili includendo detto @@ -3940,8 +4023,8 @@ accessibile con \texttt{man 7 ip}, sono i seguenti: conflitti con le porte usate dai servizi noti. \item[\texttt{ip\_no\_pmtu\_disc}] imposta la disciplina di ricerca della - \textit{Path MTU} (vedi sez.~\ref{sec:net_lim_dim} e - sez.~\ref{sec:sock_ipv4_options}). + \itindex{Maximum~Transfer~Unit} \textit{Path MTU} (vedi + sez.~\ref{sec:net_lim_dim} e sez.~\ref{sec:sock_ipv4_options}). \item[\texttt{ipfrag\_high\_thresh}] limite massimo (espresso in numero di byte) sui pacchetti IP frammentati presenti in coda; quando questo valore @@ -4053,14 +4136,6 @@ pagina di manuale (accessibile con \texttt{man 7 tcp}), sono i seguenti: \item[\texttt{tcp\_wmem}] \end{basedescript} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "gapil" -%%% End: - - - % LocalWords: socket sez dotted decimal resolver Domain Name Service cap DNS % LocalWords: client fig LDAP Lightweight Access Protocol NIS Information Sun % LocalWords: like netgroup Switch Solaris glibc libc uclib NSS tab shadow uid @@ -4133,4 +4208,11 @@ pagina di manuale (accessibile con \texttt{man 7 tcp}), sono i seguenti: % LocalWords: orphan reordering collapse sack stdurg synack syncookies recycle % LocalWords: timestamps scaling vegas avoid westwood tcpi l'incapsulazione % LocalWords: metric EOPNOTSUPP mtu hwaddr ARPHRD interrupt DMA map qlen silly -% LocalWords: rename ifconf syndrome dell'ACK FTP ACCEPTFILTER +% LocalWords: rename ifconf syndrome dell'ACK FTP ACCEPTFILTER advanced reno +% LocalWords: congestion control Networking cubic CUBIC highspeed HSTCP htcp +% LocalWords: HTCP hybla HYBLA scalable SCALABLE + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "gapil" +%%% End: diff --git a/sources/TCP_echo.c b/sources/TCP_echo.c index 6b806ac..50f681b 100644 --- a/sources/TCP_echo.c +++ b/sources/TCP_echo.c @@ -40,6 +40,14 @@ #include /* include error codes */ #include /* include erroro strings definitions */ #include +#include + +/* still not defined in some include, because too new ... */ +#ifndef TCP_CONGESTION +#define TCP_CONGESTION 13 +#endif + + #include "Gapil.h" #include "macros.h" @@ -56,14 +64,17 @@ int main(int argc, char *argv[]) * Variables definition */ int sock, i; + socklen_t len; int reset = 0; + int verbosity = 0; + char buffer[MAXLINE]; struct linger ling; /* * Input section: decode parameters passed in the calling * Use getopt function */ opterr = 0; /* don't want writing to stderr */ - while ( (i = getopt(argc, argv, "hr")) != -1) { + while ( (i = getopt(argc, argv, "hrv")) != -1) { switch (i) { /* * Handling options @@ -73,6 +84,9 @@ int main(int argc, char *argv[]) usage(); return(1); break; + case 'v': + verbosity = 1; + break; case 'r': reset = 1; break; @@ -90,11 +104,21 @@ int main(int argc, char *argv[]) * Main code beginning * * ***********************************************************/ - /* call sockaddr to get a connected socket */ + /* call sockconn to get a connected socket */ if ( (sock = sockconn(argv[optind], "echo", 6, SOCK_STREAM)) < 0) { if (errno) perror("Socket creation error"); return 1; } + /* print some info about the socket, used to test some TCP_* options */ + if (verbosity) { + len = sizeof(buffer); + if (getsockopt(sock, SOL_TCP, TCP_CONGESTION, buffer, &len) < 0) { + perror("Cannot read congestion algorithm"); + } else { + buffer[len]=0; + printf("Congestion algorithm %s\n", buffer); + } + } /* check if resetting on close is required */ if (reset) { printf("Setting reset on close \n"); -- 2.30.2