From patchwork Tue Sep 25 08:12:34 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: solomon X-Patchwork-Id: 186704 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4E4B22C0087 for ; Tue, 25 Sep 2012 18:12:47 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753761Ab2IYIMl (ORCPT ); Tue, 25 Sep 2012 04:12:41 -0400 Received: from mail-da0-f46.google.com ([209.85.210.46]:43720 "EHLO mail-da0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753726Ab2IYIMj (ORCPT ); Tue, 25 Sep 2012 04:12:39 -0400 Received: by dady13 with SMTP id y13so285619dad.19 for ; Tue, 25 Sep 2012 01:12:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :content-type:content-transfer-encoding; bh=v35g4vRhiKWkE4E9F1PkK/26HrVeR8mtm6Xzey59dNU=; b=J37lGN0bLnvWccCN30iLn/gkuf6lzdm9OWXJ9+D5Wpu+24qpisdDZF8xFNcudsJhJ8 0n6Tgzm67SzTTpAOxbN3gdU7Bco93kdq/mNn+G3m9ByybWdevvAIxl053tg9hwP75Cmr l8u4L/xYKnIhRACaSbQNpVx/TFaNR4E4z4Z8xIRT9iZjrKRb/EmCA/U1LXuVDnQo72my 5M8IruRg/M/T8ulL0Jwq/0zIyPvde7/FyqU72LFSzsbxsC/wPpS9Lcxt/QVhwaQXLAcA AWWVx+wETvONcd0K/J/J6tPytz9yHNclVoV61q3DfwmCcoHLGKmYyQGAjD0DwwthoJFz 159w== Received: by 10.68.135.33 with SMTP id pp1mr23961624pbb.5.1348560759351; Tue, 25 Sep 2012 01:12:39 -0700 (PDT) Received: from [172.30.10.96] ([112.95.138.22]) by mx.google.com with ESMTPS id b6sm10121449paz.9.2012.09.25.01.12.36 (version=SSLv3 cipher=OTHER); Tue, 25 Sep 2012 01:12:38 -0700 (PDT) Message-ID: <50616772.8040704@gmail.com> Date: Tue, 25 Sep 2012 16:12:34 +0800 From: Shan Wei User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120907 Thunderbird/15.0.1 MIME-Version: 1.0 To: David Miller CC: NetDev Subject: [PATCH net-next] tcp: avoid tcp loop connection on lo device Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Tcp supports simultaneous Connection, but we meat odd phenomenon that tcp client can receive what send by itself. tcp client and tcp server communicate through loop device. tcp server selects port 40000 to listen which is in local port range. But after tcp server program is killed, tcp client still can connect successfully. Client Server connect <-----OK---------> listen:127.0.0.1,port:40000 send(d1) -----------------> recv recv(d2) <----------------- send(d2) ----------------- killed(40000 not listened) connect <-----OK---------> send(d1) -----------------> recv(d1) <----------------- The simultaneous connection has no meaning for lo device, and for this case, tcp client don't know whether server is listen on port 40000. Just fix it sending reset to keep consistent state machine. Reproduced step: 1. while true ; do nc 127.0.0.1 40001 ;done 2. ss -nt dst 127.0.0.1 State Recv-Q Send-Q Local Address:Port Peer Address:Port ESTAB 0 0 127.0.0.1:40001 127.0.0.1:40001 Signed-off-by: Shan Wei --- net/ipv4/tcp_input.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e037697..a2f5a10 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5659,6 +5659,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, struct tcp_cookie_values *cvp = tp->cookie_values; struct tcp_fastopen_cookie foc = { .len = -1 }; int saved_clamp = tp->rx_opt.mss_clamp; + struct inet_sock *isk = inet_sk(sk); tcp_parse_options(skb, &tp->rx_opt, &hash_location, 0, &foc); @@ -5832,8 +5833,13 @@ discard: if (th->syn) { /* We see SYN without ACK. It is attempt of * simultaneous connect with crossed SYNs. - * Particularly, it can be connect to self. + * But, avoid tcp loop connection on single socket. */ + + if (isk->inet_dport == isk->inet_sport && + isk->inet_saddr == isk->inet_daddr) + goto reset_and_undo; + tcp_set_state(sk, TCP_SYN_RECV); if (tp->rx_opt.saw_tstamp) {