From owner-freebsd-net@FreeBSD.ORG Tue Mar 27 22:13:44 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 42878106564A for ; Tue, 27 Mar 2012 22:13:44 +0000 (UTC) (envelope-from nparhar@gmail.com) Received: from mail-bk0-f54.google.com (mail-bk0-f54.google.com [209.85.214.54]) by mx1.freebsd.org (Postfix) with ESMTP id C671D8FC14 for ; Tue, 27 Mar 2012 22:13:43 +0000 (UTC) Received: by bkcjc3 with SMTP id jc3so507583bkc.13 for ; Tue, 27 Mar 2012 15:13:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type; bh=uipGjIbfquNmqmnTowCEwI/O0/j4pSd0YogWGVwiurQ=; b=Gw52KI1gy1CpWaQ8uSm4GNGlrUO5E4z70v5Icd7rqU0Zmi0663t/LN/mPUfgDW/Yg6 2gebqegzbyK0UGtVfahIn6zM7xMY+MkaJ7DR+KTiLd4ZUW9k1RP63f4JCBNOxSDivS6U KfeVAGJ3kCzAsWOvZ9V+kYCxqKTG6E5oi8LytvVnBdOPawkMoScUXwQR/J8ZYSxaR+1s e50y/kP6VqxPnPBtXdQIcu0MvQfS8IvLAByV/3KTWBOo5teIDQX4YwDF+9jMoqm0QrKe ONtirwrnC4lehtkPY4vELlWmqQtwFGXzRbHjKpSLjHk/zOWCOF65DOuivGG98xLzWA2N qpAg== MIME-Version: 1.0 Received: by 10.204.10.91 with SMTP id o27mr4607216bko.5.1332886422507; Tue, 27 Mar 2012 15:13:42 -0700 (PDT) Sender: nparhar@gmail.com Received: by 10.204.202.70 with HTTP; Tue, 27 Mar 2012 15:13:42 -0700 (PDT) Date: Tue, 27 Mar 2012 15:13:42 -0700 X-Google-Sender-Auth: Ja8TNfQo5gVyNhB0cwe52ddrkmk Message-ID: From: Navdeep Parhar To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Subject: seq# of RST in tcp_dropwithreset X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Mar 2012 22:13:44 -0000 When the kernel decides to respond with a RST to an incoming TCP segment, it uses its ack# (if valid) as the seq# of the RST. See this in tcp_dropwithreset: if (th->th_flags & TH_ACK) { tcp_respond(tp, mtod(m, void *), th, m, (tcp_seq)0, th->th_ack, TH_RST); } else { if (th->th_flags & TH_SYN) tlen++; tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, (tcp_seq)0, TH_RST|TH_ACK); } This can have some unexpected results. I observed this on a link with a very high delay (B is FreeBSD, A could be anything). 1. There is a segment in flight from A to B. The ack# is X (all tx from B to A is up to date and acknowledged). 2. socket is closed on B. B sends a FIN with seq# X. 3. The segment from A arrives and elicits a RST from B. The seq# of this RST will again be X. A receives the FIN and then the RST with identical sequence numbers. The situation resolves itself eventually, when A retransmits and the retransmitted segment ACKs the FIN too and so the next time around B sends a RST with the "correct" seq# (one after the FIN). If there is a local tcpcb for the connection with state >= ESTABLISHED, wouldn't it be more accurate to use its snd_max as the seq# of the RST? Regards, Navdeep