diff -ur src/sys/netinet.old/tcp_input.c src/sys/netinet/tcp_input.c --- src/sys/netinet.old/tcp_input.c Mon May 9 09:48:56 2005 +++ src/sys/netinet/tcp_input.c Tue May 10 19:19:55 2005 @@ -1088,7 +1088,7 @@ if (to.to_flags & TOF_TS) { tp->t_flags |= TF_RCVD_TSTMP; tp->ts_recent = to.to_tsval; - tp->ts_recent_age = ticks; + tp->ts_recent_age = TCP_TIMESTAMP(tp); } if (to.to_flags & TOF_MSS) tcp_mss(tp, to.to_mss); @@ -1139,7 +1139,7 @@ */ if ((to.to_flags & TOF_TS) != 0 && SEQ_LEQ(th->th_seq, tp->last_ack_sent)) { - tp->ts_recent_age = ticks; + tp->ts_recent_age = TCP_TIMESTAMP(tp); tp->ts_recent = to.to_tsval; } @@ -1184,8 +1184,8 @@ */ if ((to.to_flags & TOF_TS) != 0 && to.to_tsecr) { - tcp_xmit_timer(tp, - ticks - to.to_tsecr + 1); + tcp_xmit_timer(tp, TCP_TIMESTAMP(tp) - + to.to_tsecr + 1); } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) { tcp_xmit_timer(tp, @@ -1564,7 +1564,8 @@ TSTMP_LT(to.to_tsval, tp->ts_recent)) { /* Check to see if ts_recent is over 24 days old. */ - if ((int)(ticks - tp->ts_recent_age) > TCP_PAWS_IDLE) { + if ((int)(TCP_TIMESTAMP(tp) - tp->ts_recent_age) > + TCP_PAWS_IDLE) { /* * Invalidate ts_recent. If this segment updates * ts_recent, the age will be reset later and ts_recent @@ -1720,7 +1721,7 @@ SEQ_LEQ(th->th_seq, tp->last_ack_sent) && SEQ_LEQ(tp->last_ack_sent, th->th_seq + tlen + ((thflags & (TH_SYN|TH_FIN)) != 0))) { - tp->ts_recent_age = ticks; + tp->ts_recent_age = TCP_TIMESTAMP(tp); tp->ts_recent = to.to_tsval; } @@ -2054,7 +2055,7 @@ */ if ((to.to_flags & TOF_TS) != 0 && to.to_tsecr) { - tcp_xmit_timer(tp, ticks - to.to_tsecr + 1); + tcp_xmit_timer(tp, TCP_TIMESTAMP(tp) - to.to_tsecr + 1); } else if (tp->t_rtttime && SEQ_GT(th->th_ack, tp->t_rtseq)) { tcp_xmit_timer(tp, ticks - tp->t_rtttime); } @@ -2598,7 +2599,8 @@ * If echoed timestamp is later than the current time, * fall back to non RFC1323 RTT calculation. */ - if ((to->to_tsecr != 0) && TSTMP_GT(to->to_tsecr, ticks)) + if ((to->to_tsecr != 0) && TSTMP_GT(to->to_tsecr, + TCP_TIMESTAMP(tp))) to->to_tsecr = 0; break; #ifdef TCP_SIGNATURE diff -ur src/sys/netinet.old/tcp_output.c src/sys/netinet/tcp_output.c --- src/sys/netinet.old/tcp_output.c Mon May 9 09:48:56 2005 +++ src/sys/netinet/tcp_output.c Tue May 10 15:18:16 2005 @@ -571,7 +571,7 @@ /* Form timestamp option as shown in appendix A of RFC 1323. */ *lp++ = htonl(TCPOPT_TSTAMP_HDR); - *lp++ = htonl(ticks); + *lp++ = htonl(TCP_TIMESTAMP(tp)); *lp = htonl(tp->ts_recent); optlen += TCPOLEN_TSTAMP_APPA; } diff -ur src/sys/netinet.old/tcp_subr.c src/sys/netinet/tcp_subr.c --- src/sys/netinet.old/tcp_subr.c Mon May 9 09:48:56 2005 +++ src/sys/netinet/tcp_subr.c Tue May 10 16:42:10 2005 @@ -622,6 +622,7 @@ tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; tp->t_rcvtime = ticks; tp->t_bw_rtttime = ticks; + tp->ts_timebase = ticks; /* * IPv4 TTL initialization is necessary for an IPv6 socket as well, * because the socket may be bound to an IPv6 wildcard address, @@ -1685,10 +1686,13 @@ * Set t_recent if timestamps are used on the connection. */ if ((tp->t_flags & (TF_REQ_TSTMP|TF_RCVD_TSTMP|TF_NOOPT)) == - (TF_REQ_TSTMP|TF_RCVD_TSTMP)) + (TF_REQ_TSTMP|TF_RCVD_TSTMP)) { tw->t_recent = tp->ts_recent; - else + tw->t_timebase = tp->ts_timebase; + } else { tw->t_recent = 0; + tw->t_timebase = 0; + } tw->snd_nxt = tp->snd_nxt; tw->rcv_nxt = tp->rcv_nxt; @@ -1833,7 +1837,7 @@ /* Form timestamp option as shown in appendix A of RFC 1323. */ *lp++ = htonl(TCPOPT_TSTAMP_HDR); - *lp++ = htonl(ticks); + *lp++ = htonl(ticks - tw->t_timebase); *lp = htonl(tw->t_recent); optp += TCPOLEN_TSTAMP_APPA; } diff -ur src/sys/netinet.old/tcp_syncache.c src/sys/netinet/tcp_syncache.c --- src/sys/netinet.old/tcp_syncache.c Mon May 9 09:48:56 2005 +++ src/sys/netinet/tcp_syncache.c Tue May 10 19:21:38 2005 @@ -278,7 +278,7 @@ * The bucket is full, toss the oldest element. */ sc2 = TAILQ_FIRST(&sch->sch_bucket); - sc2->sc_tp->ts_recent = ticks; + sc2->sc_tp->ts_recent = TCP_TIMESTAMP(sc2->sc_tp); syncache_drop(sc2, sch); tcpstat.tcps_sc_bucketoverflow++; } else if (tcp_syncache.cache_count >= tcp_syncache.cache_limit) { @@ -293,7 +293,7 @@ if (sc2 != NULL) break; } - sc2->sc_tp->ts_recent = ticks; + sc2->sc_tp->ts_recent = TCP_TIMESTAMP(sc2->sc_tp); syncache_drop(sc2, NULL); tcpstat.tcps_sc_cacheoverflow++; } @@ -688,7 +688,7 @@ if (sc->sc_flags & SCF_TIMESTAMP) { tp->t_flags |= TF_REQ_TSTMP|TF_RCVD_TSTMP; tp->ts_recent = sc->sc_tsrecent; - tp->ts_recent_age = ticks; + tp->ts_recent_age = TCP_TIMESTAMP(tp); } #ifdef TCP_SIGNATURE if (sc->sc_flags & SCF_SIGNATURE) @@ -892,7 +892,7 @@ if (sc != NULL) break; } - sc->sc_tp->ts_recent = ticks; + sc->sc_tp->ts_recent = TCP_TIMESTAMP(sc->sc_tp); syncache_drop(sc, NULL); tcpstat.tcps_sc_zonefail++; sc = uma_zalloc(tcp_syncache.zone, M_NOWAIT); @@ -1156,9 +1156,12 @@ if (sc->sc_flags & SCF_TIMESTAMP) { u_int32_t *lp = (u_int32_t *)(optp); + /* Reset the time base */ + sc->sc_tp->ts_timebase = ticks; + /* Form timestamp option per appendix A of RFC 1323. */ *lp++ = htonl(TCPOPT_TSTAMP_HDR); - *lp++ = htonl(ticks); + *lp++ = htonl(TCP_TIMESTAMP(sc->sc_tp)); *lp = htonl(sc->sc_tsrecent); optp += TCPOLEN_TSTAMP_APPA; } diff -ur src/sys/netinet.old/tcp_var.h src/sys/netinet/tcp_var.h --- src/sys/netinet.old/tcp_var.h Mon May 9 09:48:56 2005 +++ src/sys/netinet/tcp_var.h Tue May 10 19:22:06 2005 @@ -170,6 +170,7 @@ u_char request_r_scale; /* pending window scaling */ u_char requested_s_scale; u_long ts_recent; /* timestamp echo data */ + u_long ts_timebase; /* our time base */ u_long ts_recent_age; /* when last updated */ tcp_seq last_ack_sent; @@ -213,6 +214,8 @@ #define TCP_SIG_SPI 0x1000 #endif /* TCP_SIGNATURE */ +#define TCP_TIMESTAMP(tp) (ticks - (tp)->ts_timebase) + /* * Structure to hold TCP options that are only used during segment * processing (in tcp_input), but not held in the tcpcb. @@ -290,6 +293,7 @@ u_short tw_so_options; /* copy of so_options */ struct ucred *tw_cred; /* user credentials */ u_long t_recent; + u_long t_timebase; u_long t_starttime; int tw_time; LIST_ENTRY(tcptw) tw_2msl;