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