Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Dec 2015 15:39:34 +0900
From:      Yongmin Cho <yongmincho82@gmail.com>
To:        freebsd-net@freebsd.org
Subject:   tcp keep-alive message sent without timestamp option
Message-ID:  <20151224063933.GB10898@yongmincho-All-Series>

next in thread | raw e-mail | index | archive | help

--gj572EiMnwbLXET9
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi, all.

I have checked tcp keep-alive in freebsd head.
According to RFC7323, tcp timestamp option must be sent with
keep-alive packet after timestamp option has been negotiated.
So I have tested this on linux-3.13.0.
tcp keep-alive message is sent with timestamp option on linux-3.13.0.
But on freebsd head, tcp keep-alive packet is sent without timestamp option
after negotiated. So I made patch file based on freebsd head.
Please check this patch file. any feedback will be welcome.

Thank you in advance for your answers!

According in RFC7323:
    Once TSopt has been successfully negotiated, that is both <SYN>
    and <SYN,ACK> contain TSopt, the TSopt MUST be sent in every non-<RST>
    segment for the duration of the connection, and SHOULD be sent in
    an <RST> segment (see Section 5.2 for details).  The TCP SHOULD
    remember this state by setting a flag, referred to as Snd.TS.OK,
    to one. If a non-<RST> segment is received without a TSopt, a TCP SHOULD
    silently drop the segment. A TCP MUST NOT abort a TCP connection
    because any segment lacks an expected TSopt.

--gj572EiMnwbLXET9
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="tcp_subr.diff"

Index: sys/netinet/tcp_subr.c
===================================================================
--- sys/netinet/tcp_subr.c	(revision 292681)
+++ sys/netinet/tcp_subr.c	(working copy)
@@ -835,7 +835,7 @@ void
 tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
     tcp_seq ack, tcp_seq seq, int flags)
 {
-	int tlen;
+	int tlen, optlen = 0;
 	int win = 0;
 	struct ip *ip;
 	struct tcphdr *nth;
@@ -845,6 +845,7 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct
 #endif /* INET6 */
 	int ipflags = 0;
 	struct inpcb *inp;
+	struct tcpopt to;
 
 	KASSERT(tp != NULL || m != NULL, ("tcp_respond: tp and m both NULL"));
 
@@ -943,6 +944,17 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct
 			ip->ip_off |= htons(IP_DF);
 	}
 #endif
+	if (tp != NULL) {
+		to.to_flags = 0;
+		if ((tp->t_flags & (TF_REQ_TSTMP|TF_RCVD_TSTMP|TF_NOOPT)) ==
+		    (TF_REQ_TSTMP|TF_RCVD_TSTMP)) {
+			to.to_flags |= TOF_TS;
+			to.to_tsval = tcp_ts_getticks() + tp->ts_offset;
+			to.to_tsecr = tp->ts_recent;
+			tlen += optlen = tcp_addoptions(&to,
+			    (u_char *)(nth + 1));
+		}
+	}
 	m->m_len = tlen;
 	m->m_pkthdr.len = tlen;
 	m->m_pkthdr.rcvif = NULL;
@@ -965,7 +977,7 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct
 	nth->th_seq = htonl(seq);
 	nth->th_ack = htonl(ack);
 	nth->th_x2 = 0;
-	nth->th_off = sizeof (struct tcphdr) >> 2;
+	nth->th_off = (sizeof (struct tcphdr) + optlen) >> 2;
 	nth->th_flags = flags;
 	if (tp != NULL)
 		nth->th_win = htons((u_short) (win >> tp->rcv_scale));

--gj572EiMnwbLXET9--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20151224063933.GB10898>