PERFORCE change 165572 for review

Fang Wang fangwang at FreeBSD.org
Fri Jul 3 18:56:04 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=165572

Change 165572 by fangwang at fangwang_utobsd on 2009/07/03 18:55:40

	Tcp uto can work now.

Affected files ...

.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp.h#6 edit
.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_input.c#6 edit
.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_output.c#8 edit
.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_subr.c#5 edit
.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_syncache.c#9 edit
.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_syncache.h#6 edit
.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_timer.c#6 edit
.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_timer.h#5 edit
.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_usrreq.c#6 edit
.. //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_var.h#11 edit
.. //depot/projects/soc2009/tcputo/src/tools/regression/netinet/tcputo/Makefile#2 edit
.. //depot/projects/soc2009/tcputo/src/tools/regression/netinet/tcputo/tcputo.c#4 edit

Differences ...

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp.h#6 (text+ko) ====

@@ -154,11 +154,11 @@
 #define	TCP_CONGESTION	0x40	/* get/set congestion control algorithm */
 #define	TCP_UTO		0x80	/* set tcp user timeout */
 /* Used with TCP_UTO through setsockopt and getsockopt */
-struct tcp_uto {
+struct tcputo {
 	int	uto;
 	int	flags;
 };
-/* Values for flags in struct tcp_uto */
+/* Values for flags in struct tcputo */
 #define	STORE_UTO	0x01
 #define	ENABLE_UTO	0x02
 #define	ENABLE_CHANGE	0x04

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_input.c#6 (text+ko) ====

@@ -1188,8 +1188,11 @@
 
 	/*
 	 * If TCP user timeout option is received, because it's an
-	 * optional option, we do nothing at this moment. And we will
-	 * process when we need to use it.
+	 * optional option, we do nothing at this moment. We will
+	 * process when we need to use it. And we need it in two 
+	 * cases:
+	 *    1. We need do retransmission.
+	 *    2. Users request a UTO value.
 	 */	 
 	if (to.to_flags & TOF_UTO) {
 		tp->uto_flags |= TCPUTO_RCVD;
@@ -2246,11 +2249,14 @@
 		}
 
 process_ACK:
+		/*
+		* If we are sending the UTO option, and we receive a ACK acknowledge the
+		* segment carrying the UTO option,  the UTO was send successfully. So we
+		* stop sending the UTO option.
+		*/
 		if (tp->uto_flags & TCPUTO_SENDING)
-			if (SEQ_GT(th->th_ack, tp->uto_carrier)) {
+			if (SEQ_GEQ(th->th_ack, tp->uto_carrier))
 				tp->uto_flags &= ~TCPUTO_SENDING;
-				tp->uto_flags |= TCPUTO_SENT;
-			}
 
 		INP_INFO_LOCK_ASSERT(&V_tcbinfo);
 		KASSERT(ti_locked == TI_RLOCKED || ti_locked == TI_WLOCKED,

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_output.c#8 (text+ko) ====

@@ -701,7 +701,7 @@
 		 * is a SYN or SYN | ACK segment, or the segment is a normal
 		 * data segment.
 		 */
-		if (flags & TH_SYN || (len && (tp->t_flags & ~TF_FORCEDATA) == 0))
+		if (flags & TH_SYN || (len && (tp->t_flags & TF_FORCEDATA) == 0))
 			if (tp->uto_flags & (TCPUTO_NEED | TCPUTO_SENDING)) {
 				to.to_uto = tp->snd_uto;
 				to.to_flags |= TOF_UTO;
@@ -710,8 +710,16 @@
 		/* Processing the options. */
 		hdrlen += optlen = tcp_addoptions(&to, opt);
 
-		/* Check whether we place UTO in TCP header successfully */
-		if (tp->uto_flags & (TCPUTO_NEED | TCPUTO_SENDING) &&
+		/* 
+		* According to RFC 5482:
+		* "In addition to exchanging UTO options in the SYN segments, a
+		*  connection that has enabled UTO options SHOULD include a UTO option
+		*  in the first packet that does not have the SYN flag set. This helps  to minimize
+		*  the amount of state information TCP must keep for  connections in non-synchronized states." 
+		* So even though UTO options is put in SYN segment successfully, we still transmit it.
+		*/
+		if ((flags & TH_SYN) == 0 &&
+		    tp->uto_flags & (TCPUTO_NEED | TCPUTO_SENDING) &&
 		    (to.to_flags & TOF_UTO) == 0) {
 			tp->uto_flags &= ~(TCPUTO_NEED | TCPUTO_SENDING);
 			tp->uto_flags |= TCPUTO_SENDING;

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_subr.c#5 (text+ko) ====

@@ -403,8 +403,8 @@
 	tcp_rexmit_slop = TCPTV_CPU_VAR;
 	tcp_finwait2_timeout = TCPTV_FINWAIT2_TIMEOUT;
 	tcp_tcbhashsize = hashsize;
-	tcp_uto_min = TCPTV_UTOMIN;
-	tcp_uto_max = TCPTV_UTOMAX;
+	tcp_uto_min = TCPTV_UTO_MIN;
+	tcp_uto_max = TCPTV_UTO_MAX;
 
 #ifdef INET6
 #define TCP_MINPROTOHDR (sizeof(struct ip6_hdr) + sizeof(struct tcphdr))
@@ -740,13 +740,15 @@
 	tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
 	tp->t_rcvtime = ticks;
 	tp->t_bw_rtttime = ticks;
+
+	tp->uto_flags = TCPUTO_CHANGEABLE;
+	if (tcp_uto_enable)
+		tp->uto_flags |= TCPUTO_ENABLE;
 	/*
-	 * Init TCP user timeout (RFC5482) variables. We don't enable UTO by default,
-	 * but we make it available if a UTO request is received or set through
-	 * setsockopt system call.
-	 */
-	tp->uto_flags = TCPUTO_ENABLE | TCPUTO_CHANGEABLE;
-	tp->t_uto_adv = 64 * 4;
+	* According to RFC 5482, t_uto_adv is UTO option advertised to the remote TCP peer.  
+	* It defaults to the default system-wide  USER TIMEOUT.
+	*/
+	tp->t_uto_adv = TCPTV_UTO_DEFAULT;
 	/*
 	 * IPv4 TTL initialization is necessary for an IPv6 socket as well,
 	 * because the socket may be bound to an IPv6 wildcard address,

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_syncache.c#9 (text+ko) ====

@@ -772,7 +772,7 @@
 #endif
 		if (sc->sc_flags & SCF_SACK)
 			tp->t_flags |= TF_SACK_PERMIT;
-		if (sc->sc_flags & SCF_RCVD_UTO) {
+		if (sc->sc_flags & SCF_UTO) {
 			tp->uto_flags |= TCPUTO_RCVD;
 			tp->rcv_uto = sc->sc_peer_uto;
 		}
@@ -1220,11 +1220,7 @@
 		sc->sc_flags |= SCF_ECN;
 	if (to->to_flags & TOF_UTO) {
 		sc->sc_peer_uto = to->to_uto;
-		sc->sc_flags |= SCF_RCVD_UTO;
-	}
-	if (uto_flags & TCPUTO_NEED) {
-		sc->sc_uto = snd_uto;
-		sc->sc_flags = SCF_NEED_UTO;
+		sc->sc_flags |= SCF_UTO;
 	}
 
 	if (V_tcp_syncookies) {
@@ -1393,10 +1389,6 @@
 		if (sc->sc_flags & SCF_SIGNATURE)
 			to.to_flags |= TOF_SIGNATURE;
 #endif
-		if (sc->sc_flags & SCF_NEED_UTO) {
-			to.to_uto = sc->sc_uto;
-			to.to_flags |= TOF_UTO;
-		}
 		
 		optlen = tcp_addoptions(&to, (u_char *)(th + 1));
 

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_syncache.h#6 (text+ko) ====

@@ -70,7 +70,6 @@
 	u_int8_t	sc_requested_s_scale:4,
 			sc_requested_r_scale:4;
 	u_int16_t	sc_peer_uto;		/* peer's user timeout */
-	u_int16_t	sc_uto;			/* our user timeout to send */
 	u_int16_t	sc_flags;
 #ifndef TCP_OFFLOAD_DISABLE
 	struct toe_usrreqs *sc_tu;		/* TOE operations */
@@ -93,8 +92,7 @@
 #define SCF_SIGNATURE	0x20			/* send MD5 digests */
 #define SCF_SACK	0x80			/* send SACK option */
 #define SCF_ECN		0x100			/* send ECN setup packet */
-#define	SCF_NEED_UTO	0x200			/* send UTO option */
-#define	SCF_RCVD_UTO	0x400			/* received UTO option */
+#define	SCF_UTO		0x200			/* UTO option received */
 
 #define	SYNCOOKIE_SECRET_SIZE	8	/* dwords */
 #define	SYNCOOKIE_LIFETIME	16	/* seconds */

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_timer.c#6 (text+ko) ====

@@ -117,6 +117,9 @@
 int	tcp_uto_max;
 SYSCTL_PROC(_net_inet_tcp, OID_AUTO, uto_max, CTLTYPE_INT|CTLFLAG_RW,
     &tcp_uto_max, 0, sysctl_msec_to_ticks, "I", "Maximum user timeout");
+int	tcp_uto_enable = 0;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, always_enableuto, CTLFLAG_RW,
+    &tcp_uto_enable , 0, "Enable TCP user timeout option on all TCP connections");
 
 static int	tcp_keepcnt = TCPTV_KEEPCNT;
 	/* max idle probes */
@@ -159,7 +162,6 @@
 SYSCTL_INT(_net_inet_tcp, OID_AUTO, timer_race, CTLFLAG_RD, &tcp_timer_race,
     0, "Count of t_inpcb races on tcp_discardcb");
 
-static int	tcp_timer_uto_interval(struct tcpcb *);
 
 /*
  * TCP timer processing.
@@ -448,26 +450,6 @@
 	CURVNET_RESTORE();
 }
 
-static int
-tcp_timer_uto_interval(struct tcpcb *tp)
-{
-	int rxtcur;
-	int rxttimes;
-	int rexmt;
-	int interval;
-
-	rxttimes = min(TCP_MAXRXTSHIFT, tp->t_rxtshift);
-	rexmt = TCP_REXMTVAL(tp) * tcp_backoff[rxttimes];
-	TCPT_RANGESET(rxtcur, rexmt, tp->t_rttmin, TCPTV_REXMTMAX);
-	interval = rxtcur / TCP_REXMTVAL(tp);
-
-	if (tp->t_uto_left - interval < 0)
-		interval = tp->t_uto_left;
-	tp->t_uto_left -= interval;
-	
-	return (interval);
-}
-
 void
 tcp_timer_rexmt(void * xtp)
 {
@@ -508,6 +490,20 @@
 	}
 	callout_deactivate(&tp->t_timers->tt_rexmt);
 	tcp_free_sackholes(tp);
+
+	if (tp->t_rxtshift == 0) {
+		if (tp->uto_flags & TCPUTO_ENABLE &&
+		    tp->uto_flags & TCPUTO_RCVD &&
+		    tp->uto_flags & TCPUTO_CHANGEABLE) {
+			u_int utoval;
+			TCPT_UTOGET(utoval, tp->rcv_uto);
+			tp->t_uto_impl = min(tcp_uto_max,
+			    max(tp->t_uto_adv, max(utoval, tcp_uto_min)));
+			tp->uto_flags &= ~TCPUTO_RCVD;
+			tp->uto_flags |= TCPUTO_IMPL;
+		}
+		tp->t_uto_left = tp->t_uto_impl / hz;
+	}
 	/*
 	 * Retransmission timer went off.  Message has not
 	 * been acked within retransmit interval.  Back off
@@ -541,17 +537,6 @@
 		else
 		  tp->t_flags &= ~TF_WASFRECOVERY;
 		tp->t_badrxtwin = ticks + (tp->t_srtt >> (TCP_RTT_SHIFT + 1));
-
-		if (tp->uto_flags & TCPUTO_ENABLE &&
-		    (tp->uto_flags & TCPUTO_PEER_SET) == TCPUTO_PEER_SET) {
-			u_int utoval;
-			TCP_UTOVAL(utoval, tp->rcv_uto);
-			tp->t_uto_impl = min(tcp_uto_max,
-			    max(tp->t_uto_adv, max(utoval, tcp_uto_min)));
-			tp->uto_flags &= ~TCPUTO_PEER_SET;
-			tp->uto_flags |= TCPUTO_IMPL;
-		}
-		tp->t_uto_left = tp->t_uto_impl;
 	}
 	TCPSTAT_INC(tcps_rexmttimeo);
 	if (tp->t_state == TCPS_SYN_SENT)
@@ -559,8 +544,13 @@
 	else
 		if ((tp->uto_flags & TCPUTO_IMPL) == 0)
 			rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
-		else
-			rexmt = TCP_REXMTVAL(tp) * tcp_timer_uto_interval(tp);
+		else {
+			int rxtshift;
+			rxtshift = min(TCP_MAXRXTSHIFT, tp->t_rxtshift);
+			tp->t_uto_left -= min(tp->t_uto_left, 
+				min(TCP_REXMTMAX, tcp_backoff[rxtshift]));
+			rexmt = TCP_REXMTVAL(tp) * tcp_backoff[rxtshift];
+		}
 
 	TCPT_RANGESET(tp->t_rxtcur, rexmt,
 		      tp->t_rttmin, TCPTV_REXMTMAX);

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_timer.h#5 (text+ko) ====

@@ -91,8 +91,9 @@
 
 #define TCPTV_FINWAIT2_TIMEOUT (60*hz)         /* FIN_WAIT_2 timeout if no receiver */
 
-#define	TCPTV_UTOMIN	(120*hz)		/* min user timeout */
-#define	TCPTV_UTOMAX	(720*hz)		/* max user timeout */
+#define	TCPTV_UTO_MIN		( 120*hz)	/* min user timeout */
+#define	TCPTV_UTO_MAX		(1020*hz)	/* max user timeout */
+#define	TCPTV_UTO_DEFAULT	( 511*hz)	/* default user timeout */
 
 /*
  * Minimum retransmit timer is 3 ticks, for algorithmic stability.
@@ -115,9 +116,9 @@
  * networks faster then a modem that has minor (e.g. 1%) packet loss.
  */
 #define	TCPTV_MIN	( hz/33 )		/* minimum allowable value */
-#define TCPTV_CPU_VAR	( hz/5 )		/* cpu variance allowed (200ms) */
-#define	TCPTV_REXMTMAX	( 64*hz)		/* max allowable REXMT value */
-
+#define TCPTV_CPU_VAR	( hz/5 )			/* cpu variance allowed (200ms) */
+#define	TCPTV_REXMTMAX	( TCP_REXMTMAX*hz )	/* max allowable REXMT value */
+#define	TCP_REXMTMAX	64			/* max allowable REXMT value in seconds */
 #define TCPTV_TWTRUNC	8			/* RTO factor to truncate TW */
 
 #define	TCP_LINGERTIME	120			/* linger at most 2 minutes */
@@ -142,6 +143,16 @@
 		(tv) = (tvmax); \
 } while(0)
 
+/*
+* Get user timeout value(ticks).
+*/
+#define	TCPT_UTOGET(utoval, uto) do { \
+	(utoval) = (uto) >> 1; \
+	if ((uto) & 1) \
+		(utoval) *= 60; \
+	(utoval) *= hz; \
+} while(0)
+
 #ifdef _KERNEL
 
 struct tcp_timer {
@@ -173,7 +184,7 @@
 extern int tcp_fast_finwait2_recycle;
 extern int tcp_uto_min;
 extern int tcp_uto_max;
-
+extern int tcp_uto_enable;
 void	tcp_timer_init(void);
 void	tcp_timer_2msl(void *xtp);
 struct tcptw *

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_usrreq.c#6 (text+ko) ====

@@ -1256,7 +1256,7 @@
 	struct	inpcb *inp;
 	struct	tcpcb *tp;
 	struct	tcp_info ti;
-	struct	tcp_uto tu;
+	struct	tcputo tu;
 
 	error = 0;
 	inp = sotoinpcb(so);
@@ -1374,33 +1374,37 @@
 				return (error);
 
 			INP_WLOCK_RECHECK(inp);
+			if (tu.flags & ~(ENABLE_UTO | STORE_UTO | ENABLE_CHANGE)) {
+				error = EINVAL;
+				break;
+			}
 			if (tu.flags & ENABLE_UTO)
 				tp->uto_flags |= TCPUTO_ENABLE;
-			if (tu.flags & STORE_UTO)
+			if (tu.flags & STORE_UTO) {
 				tp->uto_flags |= TCPUTO_NEED;
+				if (tu.uto > 0 && tu.uto <= 0x8FFF * 60) {
+					if (tu.uto > 0x8FFF) {
+						tp->snd_uto = tu.uto / 60;
+						tp->snd_uto <<= 1;
+						tp->snd_uto |= 1;
+					} else {
+						tp->snd_uto = tu.uto;
+						tp->snd_uto <<= 1;
+					}
+					if (tp->uto_flags & TCPUTO_ENABLE &&
+					    tp->uto_flags & TCPUTO_NEED) {
+						tp->t_uto_impl = min(tcp_uto_max, 
+								max(tu.uto * hz, tcp_uto_min));
+						tp->t_uto_adv = tp->t_uto_impl;
+						tp->uto_flags &= ~TCPUTO_CHANGEABLE;
+						tp->uto_flags |= TCPUTO_IMPL;
+					}
+				}
+				else
+					error = EINVAL;
+			}
 			if ( tu.flags & ENABLE_CHANGE)
 				tp->uto_flags |= TCPUTO_CHANGEABLE;
-			if (tu.flags & STORE_UTO &&
-			    tu.uto > 0 && tu.uto <= 0x8FFF * 60) {
-				if (tu.uto > 0x8FFF) {
-					tp->snd_uto = tu.uto / 60;
-					tp->snd_uto <<= 1;
-					tp->snd_uto |= 1;
-				} else {
-					tp->snd_uto = tu.uto;
-					tp->snd_uto <<= 1;
-				}
-				if (tp->uto_flags & TCPUTO_ENABLE &&
-				    tp->uto_flags & TCPUTO_NEED) {
-					tp->t_uto_impl = min(tcp_uto_max, 
-							max(tu.uto, tcp_uto_min));
-					tp->t_uto_adv = tp->t_uto_impl;
-					tp->uto_flags &= ~TCPUTO_CHANGEABLE;
-					tp->uto_flags |= TCPUTO_IMPL;
-				}
-			}
-			else
-				error = EINVAL;
 			INP_WUNLOCK(inp);
 			break;
 
@@ -1454,11 +1458,12 @@
 			if (tp->uto_flags & TCPUTO_CHANGEABLE)
 				tu.flags |= ENABLE_CHANGE;
 			if (tp->uto_flags & TCPUTO_ENABLE &&
-			    (tp->uto_flags & TCPUTO_PEER_SET) == TCPUTO_PEER_SET) {
-				TCP_UTOVAL(tu.uto, tp->rcv_uto);
+			    tp->uto_flags & TCPUTO_RCVD &&
+			    tp->uto_flags & TCPUTO_CHANGEABLE) {
+				TCPT_UTOGET(tp->t_uto_impl, tp->rcv_uto);
 				tp->t_uto_impl = min(tcp_uto_max,
-				    max(tp->t_uto_adv, max(tu.uto, tcp_uto_min)));
-				tp->uto_flags &= ~TCPUTO_PEER_SET;
+				    max(tp->t_uto_adv, max(tp->t_uto_impl, tcp_uto_min)));
+				tp->uto_flags &= ~TCPUTO_RCVD;
 				tp->uto_flags |= TCPUTO_IMPL;
 			}
 			if (tp->uto_flags & TCPUTO_IMPL) {

==== //depot/projects/soc2009/tcputo/src/sys/netinet/tcp_var.h#11 (text+ko) ====

@@ -195,9 +195,9 @@
 	uint16_t rcv_uto;		/* received user timeout */
 	uint16_t snd_uto;		/* send user timeout */
 	uint8_t	uto_flags;
-	u_int	t_uto_adv;
-	u_int	t_uto_impl;		/* implemented user timeout */
-	u_int	t_uto_left;		/* remained user timeout value */
+	u_int	t_uto_adv;		/* user timeout send to remote peer(ticks) */
+	u_int	t_uto_impl;		/* implemented user timeout(ticks) */
+	u_int	t_uto_left;		/* remained user timeout value(seconds) */
 	tcp_seq	uto_carrier;		/* max sequence number that carry user timeout */
 };
 
@@ -250,14 +250,6 @@
 #define	TCPUTO_RCVD	0x08	/* other side has requested user timeout */
 #define	TCPUTO_NEED	0x10	/* user timeout need to be sent */
 #define	TCPUTO_SENDING	0x20	/* user timeout is in the process of sending */
-#define	TCPUTO_SENT	0x40	/* user timeout is sent successfully */
-#define	TCPUTO_PEER_SET	(TCPUTO_CHANGEABLE | TCPUTO_RCVD)
-
-#define	TCP_UTOVAL(utoval, uto) do { \
-	(utoval) = (uto) >> 1; \
-	if ((uto) & 1) \
-		(utoval) *= 60; \
-} while(0)
 
 #ifdef TCP_SIGNATURE
 /*

==== //depot/projects/soc2009/tcputo/src/tools/regression/netinet/tcputo/Makefile#2 (text+ko) ====

@@ -1,8 +1,7 @@
 #
-# $FreeBSD: src/tools/regression/netinet/tcputo/Makefile,v 1.3 2009/6/28 08:47:22 ru Exp $
+# $FreeBSD: src/tools/regression/netinet/tcputo/Makefile,v 1.3 2009/6/28 08:47:22 fw Exp $
 #
 
-CFLAGS+=	-Wall
 PROG=	tcputo
 NO_MAN=
 

==== //depot/projects/soc2009/tcputo/src/tools/regression/netinet/tcputo/tcputo.c#4 (text+ko) ====

@@ -23,15 +23,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/tools/regression/netinet/tcputo/tcputo.c $
+ * $FreeBSD: src/tools/regression/netinet/tcputo/tcputo.c 2009/7/4 02:54:36 fw $
  */
 
 #include <sys/types.h>
 #include <sys/socket.h>
 
 #include <netinet/in.h>
-//#include <netinet/tcp.h>
-#include "tcp.h"
+#include <netinet/tcp.h>
 
 #include <arpa/inet.h>
 
@@ -47,8 +46,8 @@
 usage(void)
 {
 
-	fprintf(stderr, "tcpconnect server port\n");
-	fprintf(stderr, "tcpconnect client ip port\n");
+	fprintf(stderr, "tcpconnect server port [user timeout]\n");
+	fprintf(stderr, "tcpconnect client ip port [user timeout]\n");
 	exit(-1);
 }
 
@@ -82,8 +81,9 @@
 	long port;
 	int user_timeout;
 	int optval;
+	struct tcputo uto;
 
-	if (argc != 1)
+	if (argc != 1 && argc != 2)
 		usage();
 
 	bzero(&sin, sizeof(sin));
@@ -99,10 +99,10 @@
 	listen_sock = socket(PF_INET, SOCK_STREAM, 0);
 	if (listen_sock == -1)
 		err(-1, "socket");
-	optval = 150;
-	/*if (setsockopt(listen_sock, IPPROTO_TCP, TCP_UTO, &optval, sizeof(optval)) == -1)
+	optval = 1;
+	if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1)
 		err(-1, "setsockopt");
-*/
+
 	if (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) == -1)
 		err(-1, "bind");
 
@@ -110,10 +110,17 @@
 		err(-1, "listen");
 
 	accept_sock = accept(listen_sock, NULL, NULL);
-	close(listen_sock);
 	optval = 4*1024;
 	if (setsockopt(accept_sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) == -1)
 		err(-1, "setsockopt");
+	uto.flags = ENABLE_UTO;
+	if (argc == 2) {
+		uto.uto = atoi(argv[1]);
+		uto.flags |= STORE_UTO;
+	}
+	if (setsockopt(accept_sock, IPPROTO_TCP, TCP_UTO, &uto, sizeof(uto)) == -1)
+		err(-1, "setsockopt");
+	close(listen_sock);
 	while(1) {
 		sleep(1);
 		printf("server again %d\n", optval++);
@@ -142,8 +149,9 @@
 	int sock;
 	int user_timeout;
 	int optval = 4*1024;
+	struct tcputo uto;
 
-	if (argc != 2)
+	if (argc != 2 && argc != 3)
 		usage();
 
 	bzero(&sin, sizeof(sin));
@@ -162,19 +170,13 @@
 		err(-1, "socket");
 	if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) == -1)
 		err(-1, "setsockopt");
-	optval = 150;
-/*	if (setsockopt(sock, IPPROTO_TCP, TCP_UTO, &optval, sizeof(optval)) == -1)
-		err(-1, "setsockopt");
-*/
-	/* No warning in default case on ENOPROTOOPT. */
-	/* if (setsockopt(sock, IPPROTO_TCP, TCP_MD5SIG,
-	    &md5enable, sizeof(md5enable)) != 0) {
-		if (errno == ENOPROTOOPT && md5enable > 0)
-			err(-1, "setsockopt(TCP_MD5SIG)");
-		else if (errno != ENOPROTOOPT)
-			warn("setsockopt(TCP_MD5SIG)");
-	} */
-
+	
+	if (argc == 3) {
+		uto.uto = atoi(argv[2]);
+		uto.flags = ENABLE_UTO | STORE_UTO;
+		if (setsockopt(sock, IPPROTO_TCP, TCP_UTO, &uto, sizeof(uto)) == -1)
+			err(-1, "setsockopt");
+	}
 	if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1)
 		err(-1, "connect");
 	


More information about the p4-projects mailing list