From owner-freebsd-net@freebsd.org Thu Dec 24 06:39:17 2015 Return-Path: Delivered-To: freebsd-net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2E7DCA50055 for ; Thu, 24 Dec 2015 06:39:17 +0000 (UTC) (envelope-from yongmincho82@gmail.com) Received: from mail-pf0-x232.google.com (mail-pf0-x232.google.com [IPv6:2607:f8b0:400e:c00::232]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 07F131DE7 for ; Thu, 24 Dec 2015 06:39:17 +0000 (UTC) (envelope-from yongmincho82@gmail.com) Received: by mail-pf0-x232.google.com with SMTP id q63so28140790pfb.0 for ; Wed, 23 Dec 2015 22:39:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:subject:message-id:mime-version:content-type :content-disposition:user-agent; bh=F2YrWgWd/62HB+hm6YJ5/oCSXO/5sRqBMVHuNNdbOpk=; b=nUSlHOJq1JmE7xvM2kccAi7h3ee9MKZqmdfES2j3qAmpFBI9VV6kPcmpTfkXoRF9v6 IkAEv6EqJ1drZbm+tVGqwRdiyr5mWW3ZXJLIqa/RyVC5frUOlIEJMqJ35CSWfOSGVEMr IyDCnXV91uFoorBtsJaK20rBdKDEcaw3tBGWJWbR1PL758+cez6z56Wqbj8hIEB1Sd8m 6jAlxhrgCuEa5V6R5oy/Bxa+5398Nr0gD2gTRiiJj8OeACfmlZumYs7omumdjvWplDri crECTeqhRfcBrMie9E5G6F3Ax86E/8tfvC/a49kiMTpvAfbcgc5Emk/ltsgWm2jbPUku L3xg== X-Received: by 10.98.76.24 with SMTP id z24mr28615441pfa.148.1450939156562; Wed, 23 Dec 2015 22:39:16 -0800 (PST) Received: from yongmincho-All-Series ([106.247.248.2]) by smtp.gmail.com with ESMTPSA id zu6sm39322863pac.8.2015.12.23.22.39.15 for (version=TLS1_2 cipher=AES128-SHA bits=128/128); Wed, 23 Dec 2015 22:39:15 -0800 (PST) Date: Thu, 24 Dec 2015 15:39:34 +0900 From: Yongmin Cho To: freebsd-net@freebsd.org Subject: tcp keep-alive message sent without timestamp option Message-ID: <20151224063933.GB10898@yongmincho-All-Series> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="gj572EiMnwbLXET9" Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 24 Dec 2015 06:39:17 -0000 --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 and contain TSopt, the TSopt MUST be sent in every non- segment for the duration of the connection, and SHOULD be sent in an 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- 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--