summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_seq.h
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2012-02-15 16:09:56 +0000
committerbz <bz@FreeBSD.org>2012-02-15 16:09:56 +0000
commite7eef5c8119b66a2a14b9e339e440f80c327182a (patch)
treeb0aa46ec2c710c27495fdbd3425f1e1e7f502603 /sys/netinet/tcp_seq.h
parentd93961fe9edf9c6624e6d6c918343387bf79d54e (diff)
downloadFreeBSD-src-e7eef5c8119b66a2a14b9e339e440f80c327182a.zip
FreeBSD-src-e7eef5c8119b66a2a14b9e339e440f80c327182a.tar.gz
Fix PAWS (Protect Against Wrapped Sequence numbers) in cases when
hz >> 1000 and thus getting outside the timestamp clock frequenceny of 1ms < x < 1s per tick as mandated by RFC1323, leading to connection resets on idle connections. Always use a granularity of 1ms using getmicrouptime() making all but relevant callouts independent of hz. Use getmicrouptime(), not getmicrotime() as the latter may make a jump possibly breaking TCP nfsroot mounts having our timestamps move forward for more than 24.8 days in a second without having been idle for that long. PR: kern/61404 Reviewed by: jhb, mav, rrs Discussed with: silby, lstewart Sponsored by: Sandvine Incorporated (originally in 2011) MFC after: 6 weeks
Diffstat (limited to 'sys/netinet/tcp_seq.h')
-rw-r--r--sys/netinet/tcp_seq.h31
1 files changed, 29 insertions, 2 deletions
diff --git a/sys/netinet/tcp_seq.h b/sys/netinet/tcp_seq.h
index f58b537..51d971f 100644
--- a/sys/netinet/tcp_seq.h
+++ b/sys/netinet/tcp_seq.h
@@ -62,7 +62,34 @@
(tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = \
(tp)->snd_recover = (tp)->iss
-#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * hz)
- /* timestamp wrap-around time */
+#ifdef _KERNEL
+/*
+ * Clock macros for RFC 1323 timestamps.
+ */
+#define TCP_TS_TO_TICKS(_t) ((_t) * hz / 1000)
+
+/* Timestamp wrap-around time, 24 days. */
+#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * 1000)
+
+/*
+ * tcp_ts_getticks() in ms, should be 1ms < x < 1000ms according to RFC 1323.
+ * We always use 1ms granularity independent of hz.
+ */
+static __inline u_int
+tcp_ts_getticks(void)
+{
+ struct timeval tv;
+ u_long ms;
+
+ /*
+ * getmicrouptime() should be good enough for any 1-1000ms granularity.
+ * Do not use getmicrotime() here as it might break nfsroot/tcp.
+ */
+ getmicrouptime(&tv);
+ ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+
+ return (ms);
+}
+#endif /* _KERNEL */
#endif /* _NETINET_TCP_SEQ_H_ */
OpenPOWER on IntegriCloud