From patchwork Fri Aug 23 20:45:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1976253 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=iyc/SUA3; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WrBss5kdrz1yXY for ; Sat, 24 Aug 2024 06:45:37 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E881788B3F; Fri, 23 Aug 2024 22:45:34 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b="iyc/SUA3"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C76F788B9C; Fri, 23 Aug 2024 22:45:32 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-DB5-obe.outbound.protection.outlook.com (mail-db5eur02on2071b.outbound.protection.outlook.com [IPv6:2a01:111:f403:2608::71b]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C8B098895A for ; Fri, 23 Aug 2024 22:45:30 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=NAEe/L+6elaJH/CVEL4zm7PY7t9s8u0QyM7wHgVQft5bn3iQD2OTJ3g4tJ3K74H21NyQ2qcyBjsYXJaUjYuLZyaoDlFjHEhMv8ALXGp1amZgNaqc4gHCasRXCu9v3EucOBZkLAbrA7oCS0YNE6p7asmweELnzlgxf1/OJZH6CC6hBzA039VjvYA9qC+UZUXk7pQWwZ1rJkX5HaiOMikGv3nb8AQ86/mpEAgZ2NiiDluY9ziyW+4I3vv2QO7b1Ouf6DvGAH2MD4ToEq2VLL96xMjYQQgvr4CZgez2GQbX2eMjM9+k4dhe5NlwWJ7O9mVmb1amGeoIeppBo7AdTloKXQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=/5LDNcV6ld1fkkvGz+Av9Zyvf4dlWpsdwbEWmCK0F2Y=; b=HITUd7OLGwiM6r8oSuFP4qLZUGbUabbrFWKVzEMCFgh69N7MUn3eNOJXXMdKW8tjZFwGrdcYbEy2yAba8IbXQBUNjS0ubIQfs3MWnyG6eJjHc0HKN6p7VoLMUfJv2lxwy++JlH7Gdxj4zRtIx0w/r27rQsN4Ff0yEtbZQ3UaooU7D8zsgMSOc3+37FWE7RuKeRLf3JBbEPP/PRCePMNKU3PUsBWiq4lWuasjtSjNST8u/XiL7hj9JZTqxANDOlCuFjXREYh9a9vsFlvjkqaTKo4b8Mzqa1w9ODnXaQBiovO05bipP0ax94ofpfDsHsdFPGYTc0t7rhbje+ky1XEbdQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu; dkim=pass header.d=iopsys.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=/5LDNcV6ld1fkkvGz+Av9Zyvf4dlWpsdwbEWmCK0F2Y=; b=iyc/SUA3lqmYlKaio+xxRjlPHqOWGq4kIEVkslKaUa5Ar2aoJoAPjD0Yv2RwKGuAab8XIRl1/ma6A8dlRtbI38rcahA1moMz48v/TuaxNZkNmRlZiz5b3Nxxfkfuz1jPM+zMS42bLPiwhbxztug/2OIYu9WS6ltFwHcRaeaAFZSgwKRnyYz1pijsI1AI4p3m9Cynxy5Xt/ydNP0UBwt6RMsdqTy55qgwtMhkUUrM1Em5HTB43kv67mNvmZacKQ9rHN0gQRpEh6UtBf+ZL5uFi3lUiL0gSYE8vPHyf5xFVLsuI/lHxPXy0y5TAi8JZvGxkMkIR5a4/at7JWwf9WLHHw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=iopsys.eu; Received: from GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) by VI0PR08MB11224.eurprd08.prod.outlook.com (2603:10a6:800:251::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.12; Fri, 23 Aug 2024 20:45:28 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7897.010; Fri, 23 Aug 2024 20:45:28 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Yasuharu Shibata , u-boot@lists.denx.de Subject: [PATCH v4 1/9] net/tcp: fix TCP options processing Date: Fri, 23 Aug 2024 23:45:10 +0300 Message-ID: <20240823204518.1010194-2-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> References: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR4P281CA0373.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f8::20) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB11224:EE_ X-MS-Office365-Filtering-Correlation-Id: 94096945-2bac-4c50-e60e-08dcc3b4857b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|7416014|52116014|376014|1800799024|38350700014|921020; X-Microsoft-Antispam-Message-Info: XNmhnSTNbwWry/K6/bukKpzD/zxiIaWvfcfca6S15Tkd1PEt1607w8Kaju7QeBiWKzFaUtegYy+K7u3WLvNRw7xef0qC9kQe9A51OQIKZuPddPPyRe/QIiJIrN0qcTMPI4OmCCoZDdaOVR+r43cEybQYcBpjQ7FMXFLclHW0O773rEkw1xZ+3Rxoodid5CwI7eIKlEcPV3rS2Bb5vouxJQbKTpLL51I0/9fPRJYj+3Kl33CuZETEN9EJO7WiilnvdiyVxw76GQUZc8NS7H81AfDD7mBDXwWXOu3lnbNA6b0QHFtaNrRLMaT++1vrdO3tUJ4W3oRWO74JfPFKRGBFPIDRHyyxjEObygGFDHOl40VJTD6eebjHwJkFUgiUx3fd4Z9vdW90NjnbJ0V9nPMiU2jw8zwFQcugTQTUFVM1qKAdE5AnyPuXbXroPEcSWcnQLqO4Q/LS0QQkp3hIhfujJYALc/V5ucwpQRvnwA3HDZdsV/xGvY4kVV7dPyMird/PC+LP3kt6BPNnZx7Ayu+E7tLGpjfg1/rU33CgGLbI8pF7Mb8uwXatyyuYQkBAfkwbESmeeDCnKNolm6VTErYC3cSwAjGzrmcYoNshSfgTeCjJ3HOGGJEdcj3vY96W6j7tTS5BxcjSQ9QKpONr5O7tP+MtPHjl6jwxIsWPTQFP9hZG1tbiz+zjT5SJMRBx7DjG4hmjic7QRorfxf9tW1Gp/XbyEHbVzT97triuWfUyLPMpT3JBCJEBkXzI6A8SSMReHt66JBI9BEGIgPhS8zSXuaEm4LIhovYR1AHRGdFQtqumOVmIWkfj8VsLA8Gn9sNtuVDn5H80jkFnY7NeksKAeC1t+m5hIZqUM3KQLYjXZB+yeAfQJBLh+UrcnDw0OObujd5QsJ1kFRS+tpP77MhgRt2tFt5i/5cG9i6jHXu3FdYIipv+k6NOcoKH6TGQioNlVRNMCdcr4VDq4KzwqJh1h9Zu+sJsyTwmnPx3u6YBjUIPGsTwQwnV8S2kYZceLaMyJqo2KV/uPPBpF6FVzkyORvP+N9J/UWUK57M7POQ6+yZDlwr4pDTXk60IocFwvpF2GHz9P70ZWLNHMmKnnjDFRc/17AGj8NzCflEvsqTZRA74UDxCks23oliVQ9TJZAmb2NCgPHQPGBSDjsvOkpmSxqcbkPi2LATTzJf647gfG6TURivokr+Tympw2bK+4hxeY070cBIw2goBE1lzIhhHLhrhiQqrlbaIDJIaT0IrDt5tBJ1gTGiW0Cm8qGzlwzfXYo+66qMCbzxede1rkCGbZXz1p0+vW4UDO7VNl0v9deU7dYpN+TT6G7Z0BR19NkMuOFJaCWBv1OdNaNrSA8mGI5g+PySUieTJYNPxCPOFZ2mk5kOfEUlZGiL9IeVpYpfjgDoRIjXybRzjpM7FelwAOkYvyIWPJj+VmvLwCX6tiwA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(7416014)(52116014)(376014)(1800799024)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: AQV8u4AsmwViZUnRRxoVfzebW0uqUkB0tq0xX94j1WHn5kfnR2G47wfJh6JR6Xyu3jRBE2+PrRDEuXxUeTDE6roTuBZ9BRMPs5UbMzO9SfVNdNbkJ8VQUKa6SPXiGxE33k/BYiMyMjHFBjw+tstlQXgH5koMfUh3HnhMXZIkDKPR2Cg8pI9+MnNDRXNR5DTdhI0NAYmsNq8q3nvFULr+978vsyIATrMtEMRcnlA6pbOuO1iRWbOiGoezpC8TsFKbxYQEBVi9e8xmGJO6rM7EzSz7Y/o0lxqCy8xkYYaquk7KzdL7rL/R655zeN28ViSwtFv5RK1B9ZsnuQ7ZFx67c2tuMHTM/M4Fz6Rg4ojJdPUWe9iYZDHFZKP6P8fOxVmMYBfhGxApxTxsB8QXYlNj33tr+8y+6fQGuDtiyl3+GaRU/OAr8mdI2kAy6ix4YriNPhvI3puj5nzmWc4QrK/BUT5ufmBPga2zeoV3myszTrv3aF6h1pqlS3dB+DFXIr8N4zVWhec+QEnvz7gBUGF6kRPvKgblVL7cJvag1jashfINNdYuTvNwf1C+bnk4kQCJNSKu8GiI31xMR4GsIq49T7LpDelBaCBzQ7SxWIFtkkHJ6+IantAgk1Vwxm8uJeEE13UTGOMM1RTzi2i09OtjiVSJ4NqqEHjVoeJSYQjdtp8AcaGMyGH5b3+08Idp4S6u2wlP1VQ/leGspI3+A+MwBCN1JeUH3KOY2rx/Ip2zb123zKN0TvaaFHyJ0qlmSCDyhf1JVg8KdFRCf7sVouTTI5CMl4KYnIV1RQ08lqL1rbgxc6wO+1kPJycUb4oV3C1y0fShEpVQuzB4XAsY3YAgV2E6dGD+FQfHfk0poKqtBfWi/pG7cMI+QMny0F668gD3/Vc+wKAkX2IbulTkEsMs+NIQvboTRwE0oL62JtHzttyBtLGqvZWVKpVhetERqMw5KXp6gYr7vtv2uf1cSZVAwFRv0YQRJ1AC5LX7RBJvdCzG/Eg2QoDefCBHYqWGMhiQPDRhl9qj9E4qtiJ85HhItxCaoZ2bR/wIYUjgJOx7TAKVhm86LOeSwyuWP7hckezeuyz7/0bv+NbJtqd62zJsHEDyT06BXnF0SmMpoTzbuyQCXgnMaizJmbof2gYDjTxsnV9FgH9xp4DRx7mrYBTiNEQsa5asOezL8xAkVcGg1RQM2zAbKpjiligEBrtfGN3bLi90TqA+/Z+77pJ/Jki/iBTooSYvGkKSXtv4hWJb348Gr0qJljrJ+W8kC/7kXH7Fs+B/ZH5gDjMEHuDSsllax8kPc+HbSXJc4N0KonIbJBn+uXhJ9waU3ed/dWqbUDBAA3l7j2hr9EBLcHdBxN1ahThzFOERpLaM7QXEz8Kte28QMvc5lBHysZajvD8U9up9Bu32WrkIXX4+EDZ/IfUTNLLGM8gHz6r+5h6rMHt30TUBt6CdEW8wX0hbz94ap9dbnyExNP2VN+1Zx4ZPXqXw1JnCqV8GVZccX7Ar8rJqU6J+hFSTuh5A2qxtDZIlvzekhKSA05x3v1kgbCXxEvJgThKFIACX7YRh32C3/mUHf1FNfXidvshRdogg+q2oWoRbXFIS/vASJBFEacfAvG9lwhCItBqK9TsGDwAKpn7I5hg= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 94096945-2bac-4c50-e60e-08dcc3b4857b X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Aug 2024 20:45:28.2564 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8d891be1-7bce-4216-9a99-bee9de02ba58 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 5qJQKh5rpIiod2WAg89KtQ/jgy+ItMY/XpsQEBTOGLS1NHaqPcFwSyVv65BakWl5pvtGF/kYQi2URCiCWWYGJ7H//xqqaOzi3xPmTjOYVsM= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB11224 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Current TCP code may miss an option if TCP_O_NOP option was used before it for proper aligning. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- net/tcp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/tcp.c b/net/tcp.c index b0cc8a1fe3e..3e3118de450 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -475,7 +475,7 @@ void tcp_parse_options(uchar *o, int o_len) * NOPs are options with a zero length, and thus are special. * All other options have length fields. */ - for (p = o; p < (o + o_len); p = p + p[1]) { + for (p = o; p < (o + o_len); ) { if (!p[1]) return; /* Finished processing options */ @@ -490,12 +490,14 @@ void tcp_parse_options(uchar *o, int o_len) case TCP_O_TS: tsopt = (struct tcp_t_opt *)p; rmt_timestamp = tsopt->t_snd; - return; + break; } /* Process optional NOPs */ if (p[0] == TCP_O_NOP) p++; + else + p += p[1]; } } From patchwork Fri Aug 23 20:45:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1976255 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=MQIr4hLQ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WrBtF0q9Xz1yXY for ; Sat, 24 Aug 2024 06:45:57 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id AE70E88BB2; Fri, 23 Aug 2024 22:45:36 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b="MQIr4hLQ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E47C188B47; Fri, 23 Aug 2024 22:45:34 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-DB5-obe.outbound.protection.outlook.com (mail-db5eur02on2071b.outbound.protection.outlook.com [IPv6:2a01:111:f403:2608::71b]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 35B2688B5D for ; Fri, 23 Aug 2024 22:45:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=cjNYq8Ole5+Slkqjlz9wMlbMkfC9zBDn4d7y51y3dIn8xb0+l30MjQr+/bsx9rebjY/oMXrXJDzeSrxFeBnd6lGah/5cBsn/2rIwcIzOloUwuHil3vAhkPlqYUgc+xHetF2v0QpClN26IA/SGlYhtaUuorhIYiMHW7xoy1aLvLliEhq2eLEFUthXpg/daPprEqzn8BhR+VaSamNww84qtRrLwwHM7pnJ8ANwZhSIFmLN115OpGhDgo7EC1OklYDitsNHdtfL8e+5au/vzo5vpaQ2F7e6hoyd+LMPdis7ZKESkGODzG89+Wl6iRrQ9WhDOJmr5CugcyYpLgxbwp+ZEg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=hahBnFJbV0odlIPukazF5oQypFtjvGWCc6V4kSoQSX0=; b=yvBov8bGmblQi4OVjtiJuQPGxV/R6QGJ6iYcWgAVPHKVFMgJzEu8AJi3PZV6hrz/+iFvNxhN+wD6zBxBQ/Z+TR9HmZHu+4qTp2vAI01NuhWz9OD+LFzER/xqfC6zXun54HgH0NIU/ALOdPT0C570sMHiVZit2E+EWSimxyAUFWED2GgPKUZazEib61PmtQ9i3j4u9iN4GqV4y8BfLsNI6AcsRfEB7H285oS7e/bfP0yaQgePsgKcjkEylK2DBLQQ6A1UDeolZcVmNHa/eRcEOzkGDRsXbuvbkseLRdyWlNpy+7U+o6uxrgflZoK1kuv3V/k0K7J+/JpemUgCDsoImg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu; dkim=pass header.d=iopsys.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hahBnFJbV0odlIPukazF5oQypFtjvGWCc6V4kSoQSX0=; b=MQIr4hLQpMFU9EhMP2NHb9eOUUT0Z5PwqLOErutN09SvSxAvr6/Gvq9QhWlFMwFnHdEoyU3i/mTxmfOQnLMFwilWIbvdKiwMmPiK/RMDNG+Wr1IUUFl6A1Uu29JOjxr2S2DqN1XJEwaQbx1/3PqajK35eNUJoqneuL8hw9b4mQSbe/4WcF2rUKXAhwiDpHYZln+bEDuXc7TH6KPlbRc22ulbBgB4gbvflUvyO0U//+0QweK834t1GKWlA99OswivPQZH5DIgHDAssOunRUfaUB72wMbCMd/RGZS1va8iUAOhptcPzmH299F4so2zZkq3gJ3MYHcwctowXALefjJ6Ow== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=iopsys.eu; Received: from GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) by VI0PR08MB11224.eurprd08.prod.outlook.com (2603:10a6:800:251::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.12; Fri, 23 Aug 2024 20:45:29 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7897.010; Fri, 23 Aug 2024 20:45:29 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Yasuharu Shibata , u-boot@lists.denx.de Subject: [PATCH v4 2/9] net/tcp: fix selective acknowledge Date: Fri, 23 Aug 2024 23:45:11 +0300 Message-ID: <20240823204518.1010194-3-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> References: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR4P281CA0373.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f8::20) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB11224:EE_ X-MS-Office365-Filtering-Correlation-Id: a9235e9d-a15b-4260-2976-08dcc3b48642 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|7416014|52116014|376014|1800799024|38350700014|921020; X-Microsoft-Antispam-Message-Info: OMCRj5qZnRoGaFBm+QNvV6nlNuyCBW+ourwJfvT39XseLxFVuDT/7VupQMeuqVX+KUV7AvYxD9jU1+tAYfcq5h0EuaCQcRcuwOCBGGrXccf2u9VNAwE8M5nAhtjRh1JPBneWpt/0x8pWVKgiMg9c6TmaCIFoBaPIy3kkgG5Eti0GR2Z5UKy5R896U4p10GMFN+sCka+i/Xz8bt9h/yyXo6FX1QQRzUMB2Oi3J7Z3T/ddENibmO7QaFUsBhEHXdVDufXauvgzZtKwjBn3apQX+6h5RkYwB7TXoBf0BKALu0tQbLgMDOmkK3vpd4W1MmTBZi/ruyv9awhJvJlEi1NxJqFuGB4ZyYXoB4hyuVbknxgraFEApnQNzjEKbRN0rTOpAl0UOYaxJcu7Xsc/OgUf5hUZBdQAg6D8ZlB6lkEZ/YdyYnY1ouiBq2VVm72AyBB98wO6LwWbC1U1oUjLRLxwzxOs/J4uGVNOdPxOINZSpS1+4Rbq7kf07FPGASnByLS2XXT/nIfy/uA27Av/2qo4oeZnl0Jw/K0bRfcDSjU9a4si2CQA0znHnzuaUwxdKzUQqzZ5D9LsIT32lILDvx7YCWqraG8qFIuK6t15Kso56ggwTV8jtMnDMYO4FIixvhpiMO5r6TMgL8yqToI+Smq6umRNCIrZ9y09YOphT66l+OEzBG3d7WvXzVI+UdeVuKSNUxg/g4Z9cKuXwuxYHIgeRbI5sODIHXutkEvPbz/CR+A7TDnxM7aNdij+6ZKRORg8xTtzMsVXrDUFNgXz3RHtBkctIs8U2M9TS6aNI5X6qi3N+s2BoANuldwqvXvqNmSkT9BS5kexX18HknqiErHAVvAy2JVCWyi/xatJNissNZZ+V+uNr+CRA40inEAwECHwIu1cvoBVitec36AUoAD6q+bmdVPN2HYFy8AYEQiIZfmxfGY6lBB2MacLHftbJqhb/LlZmJrSarskwFzUKkIcKwwjaIRUX8q5oaVm++uELoT84Og3We8KtcQc/qznSk/c/CGUmoAB1meVai79O01fGr2TdFbSX2q7cnB95OSbd84yWPRKRkX/2Q5I1oGqiDMEslk4C0P1zy2drSGtMlZrJ8HC6MgoRXYMGETOMUwY+C2D1M/F7S600WgNhkQ1tEwo93/hldm7a0V8aLRFUtHYGwNDlIBEMJaT6VpK3Fn/1yUD4+4MzEc3+CfqyWFxSFJNtizC2G7o2zS4WZaD90LjmLyxe1QI6q/Cfk6QmDmPpcvduS1Vbxw6ZVObeX9jH93iXaT0Td89GdV1RLWswmZDipKmRdrSXzFX5B2o3OrAP9raABqO+5WSUgDfzOBEHU6dn8tpZlc5kThyHcaPuy7eDqpDZUYzDS1lEX0U9CDhqEGyZ5PqIQWncZabTYDtP5ZJY8+5Xop1RP4mSVXJKw2zz3ev+RkNXFRSsLutbCsX4X0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(7416014)(52116014)(376014)(1800799024)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Sq/T129edWeSVxVEYdkqXiNzFyy7iky18Fv4pLTqDB9x2tSWEPj1VShlaD6vsMwbrYASxbWVGKIhMgnFIVCShZgDqJ3BIU80m7OA05vhnIRzvE27YiJUN9lyenU/GWVUvraacdNgdy0cycZDUIoqS+ZwIh3LmxU4YnmdRuW21SEXEdlI4CThgyLC7DTJeLkVac8Xzdtl4wZXzeH9MFFnD/AGZDSEb0ya2q+0jk88hqz4t2j4On0dccdV6sMSxwhBhZiN+o8xhRM8UeQvsnYfKU4tkOUqkU2pw+2bCTrWZKyyVTDFPp/5tZP427GkvrIT5cHYAWlJs2l1Dgtowyo+8xgE7eheywU7jRI7S9zveV2mh8o92KznU9ialUEJ2mjWZlF02AqcUO60tdj/VodP5EeDeyrgDT+AHlCkHjTBZiL9ohybpIxsWJx3NkmBV6itpJor/CZ/KvW3fqTKrHPWMnbSt5SXw8DmekqPYT0AX/VAqbW4C7r/XrIWb8F+w+aWUMhK7jE7NQE0JUN02qfnNFTzCXiKGd3qWbS0OA6mwLr6VvTjSMyk+PeBAcp4VJzweCyhQHEQz+aQ4WTGTf3XIJYSE2wkUKLEXqjIo3sl1iJpBaI1uQeRWCjJScjyaya5VdWzcAoXuYQTGr7perNwUn760WX6P1vp16igbhCCv1B36l7UbF/88fwSl5omBE+b6T15/s2GebCeJAEcmvBS1ARhgizgboCpw9cu0wjoeIzqWP5PUUmuzAdExYGxvx+HcF3NrsSAUp86ACpz9YRP6+czeJS+x/b8ej6pDj7fmJyKmca6K0fi1MNx0UnWAZneY0JE6W6qGMoRLJSOuyokER3IX5MTZ65jlo1NmXf7vUJqmom+lmXDtgnpVDK7IjwsQN/I1iUlGCVC8KdWFwFLaHvxxsARUdC1Eb4yuarCXWX49KoGydj/7r3xgv3RBFbNPr9YVMQoOpY1jWQ4T42yR0VnxAxW5xFde3cjsbYD7hb+avpdlyp5PvDTU/ynSdFlmiAPYPqyD2pubhEd4bn9bpXxHBcZK7TLb+mgVXnLiFVGXMbBNk5rNfa6dcGG1g6OtLlayJbSLg2hNx/9vE2XcgIPhxKDvx1S23tyb1aZcgk9FfxOi4Yl+Bv0oEl9iPOk4/MPaFIUBbETJPCVNe7EbS3GneXbywjEsip+Q6dF2jdjC8RiApbrBxnRgzbPr5M60lCqBk0sQ4ivj0n78sw+mLtQI1s69+FbfhuslyjEsWZoF5dsLmiw0itxZ4td/jkho9T7LZg+dEzelqTeoV6QFgqDOlpfA3DDS1xRA96KpMyKafvXsjxClquF+36rZXVhy41cArCkvJRhYty+ot6n7ALw6LJALY4/Ci6q1N7jDS/j0re0qBIArjgR3DHNNkEqeT4od9AgWysucpVzMwkZCQk7yenHnHPJI7qIzqX+sKtBta3ldaNQBy28m3hODSmdbVOwMzR0chGifKzpsGCdkxP0GzBlYqW6hvTYvwlrccogQ0D0osQZE6/ORlHCXPXuITFQpBD3axc3RTpFGwcMdbjLWWqnSeIu+eafbU8kGBHQ0nQrJaZnmbLWF9HRDzN0D36+aoXnZ1WALegB4cSF59TDAcJTZyWbQD+tEHRprtI= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: a9235e9d-a15b-4260-2976-08dcc3b48642 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Aug 2024 20:45:29.5383 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8d891be1-7bce-4216-9a99-bee9de02ba58 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 00jmhKW6g9B2VAUJZ9xdnhmq1nifWNgb0K/ri98vmIPws91BgmSuybEg3qS+F5u/exJ8lGknIDyPqqhyQitPZHlnrux4UEMLcrskNs7G9u0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB11224 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Current code assume that all (except last) packets are of the same size. This is definitely wrong. Replace SACK code with a new one, that does not rely on this assumption. Also this code uses less memory. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- net/tcp.c | 200 +++++++++++++++++++++++------------------------------- 1 file changed, 86 insertions(+), 114 deletions(-) diff --git a/net/tcp.c b/net/tcp.c index 3e3118de450..724536cb352 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -38,21 +38,6 @@ static u32 tcp_ack_edge; static int tcp_activity_count; -/* - * Search for TCP_SACK and review the comments before the code section - * TCP_SACK is the number of packets at the front of the stream - */ - -enum pkt_state {PKT, NOPKT}; -struct sack_r { - struct sack_edges se; - enum pkt_state st; -}; - -static struct sack_r edge_a[TCP_SACK]; -static unsigned int sack_idx; -static unsigned int prev_len; - /* * TCP lengths are stored as a rounded up number of 32 bit words. * Add 3 to length round up, rounded, then divided into the @@ -69,6 +54,11 @@ static enum tcp_state current_tcp_state; /* Current TCP RX packet handler */ static rxhand_tcp *tcp_packet_handler; +static inline s32 tcp_seq_cmp(u32 a, u32 b) +{ + return (s32)(a - b); +} + /** * tcp_get_tcp_state() - get current TCP state * @@ -267,6 +257,7 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, action = TCP_FIN; current_tcp_state = TCP_FIN_WAIT_1; } else { + tcp_lost.len = TCP_OPT_LEN_2; current_tcp_state = TCP_SYN_SENT; } break; @@ -353,6 +344,20 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, return pkt_hdr_len; } +static void tcp_update_ack_edge(void) +{ + if (tcp_seq_cmp(tcp_ack_edge, tcp_lost.hill[0].l) >= 0) { + tcp_ack_edge = tcp_lost.hill[0].r; + + memmove(&tcp_lost.hill[0], &tcp_lost.hill[1], + (TCP_SACK_HILLS - 1) * sizeof(struct sack_edges)); + + tcp_lost.len -= TCP_OPT_LEN_8; + tcp_lost.hill[TCP_SACK_HILLS - 1].l = TCP_O_NOP; + tcp_lost.hill[TCP_SACK_HILLS - 1].r = TCP_O_NOP; + } +} + /** * tcp_hole() - Selective Acknowledgment (Essential for fast stream transfer) * @tcp_seq_num: TCP sequence start number @@ -360,106 +365,79 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, */ void tcp_hole(u32 tcp_seq_num, u32 len) { - u32 idx_sack, sack_in; - u32 sack_end = TCP_SACK - 1; - u32 hill = 0; - enum pkt_state expect = PKT; - u32 seq = tcp_seq_num - tcp_seq_init; - u32 hol_l = tcp_ack_edge - tcp_seq_init; - u32 hol_r = 0; - - /* Place new seq number in correct place in receive array */ - if (prev_len == 0) - prev_len = len; - - idx_sack = sack_idx + ((tcp_seq_num - tcp_ack_edge) / prev_len); - if (idx_sack < TCP_SACK) { - edge_a[idx_sack].se.l = tcp_seq_num; - edge_a[idx_sack].se.r = tcp_seq_num + len; - edge_a[idx_sack].st = PKT; + int i, j, cnt, cnt_move; - /* - * The fin (last) packet is not the same length as data - * packets, and if it's length is recorded and used for - * array index calculation, calculation breaks. - */ - if (prev_len < len) - prev_len = len; - } + cnt = (tcp_lost.len - TCP_OPT_LEN_2) / TCP_OPT_LEN_8; + for (i = 0; i < cnt; i++) { + if (tcp_seq_cmp(tcp_lost.hill[i].r, tcp_seq_num) < 0) + continue; + if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num + len) > 0) + break; - debug_cond(DEBUG_DEV_PKT, - "TCP 1 seq %d, edg %d, len %d, sack_idx %d, sack_end %d\n", - seq, hol_l, len, sack_idx, sack_end); + if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num) > 0) + tcp_lost.hill[i].l = tcp_seq_num; + if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num) < 0) { + len += tcp_seq_num - tcp_lost.hill[i].l; + tcp_seq_num = tcp_lost.hill[i].l; + } + if (tcp_seq_cmp(tcp_lost.hill[i].r, tcp_seq_num + len) >= 0) { + tcp_update_ack_edge(); + return; + } - /* Right edge of contiguous stream, is the left edge of first hill */ - hol_l = tcp_seq_num - tcp_seq_init; - hol_r = hol_l + len; + /* check overlapping with next hills */ + cnt_move = 0; + tcp_lost.hill[i].r = tcp_seq_num + len; + for (j = i + 1; j < cnt; j++) { + if (tcp_seq_cmp(tcp_lost.hill[j].l, tcp_lost.hill[i].r) > 0) + break; - if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) - tcp_lost.len = TCP_OPT_LEN_2; + tcp_lost.hill[i].r = tcp_lost.hill[j].r; + cnt_move++; + } - debug_cond(DEBUG_DEV_PKT, - "TCP 1 in %d, seq %d, pkt_l %d, pkt_r %d, sack_idx %d, sack_end %d\n", - idx_sack, seq, hol_l, hol_r, sack_idx, sack_end); - - for (sack_in = sack_idx; sack_in < sack_end && hill < TCP_SACK_HILLS; - sack_in++) { - switch (expect) { - case NOPKT: - switch (edge_a[sack_in].st) { - case NOPKT: - debug_cond(DEBUG_INT_STATE, "N"); - break; - case PKT: - debug_cond(DEBUG_INT_STATE, "n"); - if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) { - tcp_lost.hill[hill].l = - edge_a[sack_in].se.l; - tcp_lost.hill[hill].r = - edge_a[sack_in].se.r; - } - expect = PKT; - break; - } - break; - case PKT: - switch (edge_a[sack_in].st) { - case NOPKT: - debug_cond(DEBUG_INT_STATE, "p"); - if (sack_in > sack_idx && - hill < TCP_SACK_HILLS) { - hill++; - if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) - tcp_lost.len += TCP_OPT_LEN_8; - } - expect = NOPKT; - break; - case PKT: - debug_cond(DEBUG_INT_STATE, "P"); - - if (tcp_ack_edge == edge_a[sack_in].se.l) { - tcp_ack_edge = edge_a[sack_in].se.r; - edge_a[sack_in].st = NOPKT; - sack_idx++; - } else { - if (IS_ENABLED(CONFIG_PROT_TCP_SACK) && - hill < TCP_SACK_HILLS) - tcp_lost.hill[hill].r = - edge_a[sack_in].se.r; - if (IS_ENABLED(CONFIG_PROT_TCP_SACK) && - sack_in == sack_end - 1) - tcp_lost.hill[hill].r = - edge_a[sack_in].se.r; - } - break; + if (cnt_move > 0) { + if (cnt > i + cnt_move + 1) + memmove(&tcp_lost.hill[i + 1], + &tcp_lost.hill[i + cnt_move + 1], + cnt_move * sizeof(struct sack_edges)); + + cnt -= cnt_move; + tcp_lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; + for (j = cnt; j < TCP_SACK_HILLS; j++) { + tcp_lost.hill[j].l = TCP_O_NOP; + tcp_lost.hill[j].r = TCP_O_NOP; } - break; } + + tcp_update_ack_edge(); + return; } - debug_cond(DEBUG_INT_STATE, "\n"); - if (!IS_ENABLED(CONFIG_PROT_TCP_SACK) || tcp_lost.len <= TCP_OPT_LEN_2) - sack_idx = 0; -} + + if (i == TCP_SACK_HILLS) { + tcp_update_ack_edge(); + return; + } + + if (cnt < TCP_SACK_HILLS) { + cnt_move = cnt - i; + cnt++; + } else { + cnt = TCP_SACK_HILLS; + cnt_move = TCP_SACK_HILLS - i; + } + + if (cnt_move > 0) + memmove(&tcp_lost.hill[i + 1], + &tcp_lost.hill[i], + cnt_move * sizeof(struct sack_edges)); + + tcp_lost.hill[i].l = tcp_seq_num; + tcp_lost.hill[i].r = tcp_seq_num + len; + tcp_lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; + + tcp_update_ack_edge(); +}; /** * tcp_parse_options() - parsing TCP options @@ -509,7 +487,6 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) u8 tcp_push = tcp_flags & TCP_PUSH; u8 tcp_ack = tcp_flags & TCP_ACK; u8 action = TCP_DATA; - int i; /* * tcp_flags are examined to determine TX action in a given state @@ -536,6 +513,7 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) action = TCP_SYN | TCP_ACK; tcp_seq_init = tcp_seq_num; tcp_ack_edge = tcp_seq_num + 1; + tcp_lost.len = TCP_OPT_LEN_2; current_tcp_state = TCP_SYN_RECEIVED; } else if (tcp_ack || tcp_fin) { action = TCP_DATA; @@ -552,13 +530,7 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) action |= TCP_ACK; tcp_seq_init = tcp_seq_num; tcp_ack_edge = tcp_seq_num + 1; - sack_idx = 0; - edge_a[sack_idx].se.l = tcp_ack_edge; - edge_a[sack_idx].se.r = tcp_ack_edge; - prev_len = 0; current_tcp_state = TCP_ESTABLISHED; - for (i = 0; i < TCP_SACK; i++) - edge_a[i].st = NOPKT; if (tcp_syn && tcp_ack) action |= TCP_PUSH; From patchwork Fri Aug 23 20:45:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1976257 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=ftbH1stf; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WrBtc5lSwz1yXY for ; Sat, 24 Aug 2024 06:46:16 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7C07B88C13; Fri, 23 Aug 2024 22:45:40 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b="ftbH1stf"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 01B6E88BC3; Fri, 23 Aug 2024 22:45:37 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-VI1-obe.outbound.protection.outlook.com (mail-vi1eur02on20700.outbound.protection.outlook.com [IPv6:2a01:111:f403:2607::700]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 60E0588B84 for ; Fri, 23 Aug 2024 22:45:32 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=glUQn6eILH9qJMDCg8jO8GHeLCmE4eBz9FHGGBM2KJvhkHRNe3tTCNb68oyhD0I2+/WEW56xIYLONe3Le6hLkPvuIcYiZt2Wx4Am8tbotQf6tONFybRowWjWg7fNW0dXTezU0/72fdrUAiALBIm9VYX/12m74sUZ1g79cy+d7Q6NtUCmTZL0dUigf3mwR8Y7cIfnAk7LULGHedwXDZkUlMh6jh8zisL7GCYIcatd3ga8bDsSedX+xGtZKFJKDpxOCLEaovIoZJfe6xSGqGOOjYMLzH/JyLRZKv0G/WkT3gDUcuFTIayeLeZIbDU/nEPhgdqrQyCyjApkHaI5DnJd/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=+2S0JGgngRg3t88tBV2E65cdwVGw5CdjN8FATQn64pg=; b=cG4tmha0frAuZTbQF0yqTFscEG4evi0NyyXuAvju2QAH7zUF++UYO/QvmYbunkxrSUbkwcNVG8AUwRJD07tkJCp43xJ20NKsTMm7cp6ymYRlcljU8aZCCG1EdUQr9/EohgxkPSYykJPmxvI/d9dpDFahQ5ZFx0853aeELFjW2b5avh8CI8wcZBZsji4elPiANDGLyVzNBWqquCiFLhBugRvt7aTCnpx3i+qz8kpWBK/LYQpvDzLVFDikaHwa731et1Rsz2M6YZAtlo6Vtk5WZ1M05KmhA1I/0RckNDut3SqxvTFlZmUjMpv0Vr0f+3QuZpzzVoJcu0rC/HOeDTIsdQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu; dkim=pass header.d=iopsys.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+2S0JGgngRg3t88tBV2E65cdwVGw5CdjN8FATQn64pg=; b=ftbH1stfN5rTQbzkbUT9v4lTfO7uH3Pld8hUs8m81mh4ryIEiDsEzc1tkFsYYHZmr96TbsnAqoA3lq4c6aex8GDT1OXhR4tfKq9AetUyMSdw0hhJVQqES7zTcuUb42PkrPFqBK9mZzGIkxfCzhZQgqDpdkV7rmM/lRbp/eaxPWuf21M0flnW2lkFr2oOsr9wso5XAFucO7U/Wn12LwakAWBpxUPyi21CROaMPWdxtR03i+fblFE9kecpFaRkg91ba6T7tANJ60/bQUTPJ9sq55ivLVRJ17SVGIV+gaF49333ZYSN65EADuRWCteLdx+mOB3c7amlMzLn4a6LRsYQng== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=iopsys.eu; Received: from GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) by VI0PR08MB11224.eurprd08.prod.outlook.com (2603:10a6:800:251::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.12; Fri, 23 Aug 2024 20:45:30 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7897.010; Fri, 23 Aug 2024 20:45:30 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Yasuharu Shibata , u-boot@lists.denx.de Subject: [PATCH v4 3/9] net/tcp: put connection specific data into a tcp_stream structure Date: Fri, 23 Aug 2024 23:45:12 +0300 Message-ID: <20240823204518.1010194-4-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> References: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR4P281CA0373.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f8::20) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB11224:EE_ X-MS-Office365-Filtering-Correlation-Id: f0b5a134-9829-47ff-9067-08dcc3b48707 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|7416014|52116014|376014|1800799024|38350700014|921020; X-Microsoft-Antispam-Message-Info: X24gVNoeOKrLBI1nGcmh4LW7YljI622JqLDCcXFRh/i3ex4Vc6vpEBiB8QDKN3jsKkaQWbL6DSBLFgaMbQB73xvuB/OjMJ4qVoG2XiXERB7AI4HvFKBSzhBkv4HuUwaXs3UbAi6dUIE+Fw2veQXi8zS62inoxWgllE+LTLxZbbeizXZ1qnwKWnzPjnMEQP4M9a4V2ExTenem4+ZnF1obCnW/QLlXrNYelakjPqILHbCfeq5rfRe3Gt+LHkY1IaNhx5yX53njjWzWoIOrO1zQowt94HWcRfpBaBDrBD5bU0VbwK1IoObinuOA7rhs5mtcBCC+0eztMLcAAX7AiPShAWA3r00Y85j0iI75hO1zjtguhGh6VUiYnBnPnJ4g1D16mLNZkEfQTzy9Dc5bjs+8Z4rvTxP0sADZNHMJwnvFzAcliSanR7lgd2Y1XQGAn1bYGzGBvWAFWiI/E17wShAkx3iMHa1UN8Q4ACk7qp5dgyL7/5fgxER0nXf+BFK8WPGB2xbBxGeI6ot+QfmFKng0zSUt9UbX9NbiknpwfFK+AOyT9cWcmH/Y0WbJVRSD4WzGUR/kqofbLkT+kWxkoCqWbdUPtYT0E2wUjjbEA+coLtqykhxA1mgVvwFUA7jfrBBMEMR7LBso7YVhBHxPd16Q9wKUWS+tVxAxJekc4zn6G1IVIJkEPEFejF4/ZKsH5t48sWZdoD9nn1djPF/ms3+IKrt/yqilu2opgCMSzjydYGAKcCX9JvPT9mNOj5N476k7AzjG4YocLWLujspeiD/jyAjFvQWC67OPKN7r4q7oq3x9SKjWL1vFN3ErGK0nfSnOnscjoR74FJPappk+qku7hIzyYmdZymgRlTxLN75YIIw+72J7KQ9+04PbXCSGOhA8sLxjEPnefZzJBTcqwNCL5kQH68fOzEdPLjPNAHRc7mInWOnHxPVoThfWuu7yX4blz2BgrNjAHXuxdd7cJjHVwxykVaw8sB3gtguI4zSDA2Hy5IAlNfwKDaZoT2tJBB6GM8m2v+KvnO3gQGklEJ/MmyapugExZ5OCvaxaF0DMrdoMACug1bneVxSvZxppixEUmJcu7HuALmAv4iWdaN57KSU3Vetlr6OHevRuB6DgRxXx4OleShjquRi2KgDByMV8CdXZiOPjHm4trNWwf7ncXzzPpzy1hP/y02Ddc29i6FSVJPINoheLn7uDOGpJOYJV80PICUAak6lB70GLTcIrrUecc+UeJJ9XHgim+mSDhNCX1w1GR+rkcDwsGKc3SLMGy7nnCyeT0adFkDniFrFyrz3NHZ/oiDT7u5WxI+1jgleShEU4AQKakilKUM+uc1ZjMyw7fDzfrgF2q12vyS6eGPLFdZxzyEvhasXzYnMpAWpistAhyvGvwS7xW9mQrclA5VzxOwNHEF2ucI2GaILS12vdiuFcOha1NP4+959Ysjw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(7416014)(52116014)(376014)(1800799024)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: r9qQV3U/czYNUBqGIVjjZIK/0kEVcg9DASRjgBl65BOWsJjWBF213BIzg45xOoLDtKPBfidtPPCboRCeMLGLDxgLPt2x28336dcFkQ0vpCaBkgNyLlTYhRZn/SnhFxL71j9VOc/nzF2N9XqASnbPS9p0AYvFReqIUDmXax/9xYRIARYPL79dcaoirkzFJt63/jNpLOWDDmJHNqK0AqHHFP57cdEiLB62Yb7kYkK9/Y8z/Y0DTclC7kR4NxZ7kEwYZCCMyU7WgC3dYysLwi6v4IQPiScXoFwiuDu7QKNND4a8MLnxv9rQZXVAYSrGML9HsgZ6uSZdC9pzrYq989CoTa1uOlMIM9oISk2IdexusdRNsH/QWYjMkJqG4jC//Tjk/xJ4VQx5AurWXAow7OFbIn3wXT5tbtjDEy+sjl7yXyw63TNLbRLg3wENLP3rZFKAebo8WvmHfe96I6tDC/Jfx7LThuQzrg0yC2BZtMtwIBVrpfrPZBP7RW9LmOpVvGVf19sh3a1OaJ0qbnEGVELucC4w00Sui3qMOZXfG63ZfyX+dFh+kNS1ThKbxfLTNErzLzx7R4SGEgQaevC6WqFntrKb7bhID1qP0mSX9zPb5veJI1veBV1K7S96OxxkwJIxaeHrVo9T4mSbTelhii6W44cU92S3tMzLhS6xR51uwMyJDHTyMYbE+MwA41OivGaAgzmDokNi9033IeFC568mBrf827sHgWBKhPpiikilFFkgNhYUM/BfOka1j8zJ2TTM3r1FNK2MfUT8WGltDy1DFhPMY/S4v4wgVz2LE6SeH0HXkfWJ8eTDIxzYnpn0dfyeJ1IGPY85wj2kmRZOfuquprXLR6XdeN/fn7y+2ZuP3XsW7WLY2ySqrxeSV/UoVWBL3wE3hKcgqs0OCujh65mIdwOasnmOb2JJJ2K0bLcQNxLcDJckccGo8vkbAAO5xFP8R5GcXIFwH6pysgXwk9xbSb1zHAy46Rh/rWCkpM6NxMt3HUl5jJoTeoCi/LjJqJKQXkgFdtoW2rtzWSP+0WIpreTw8SMcAlzC1F2dKpSpfUBe8za4JwSqwE1Eab1sDEEOOrujwzZrc466uNjArkw6w4n5IT3Tr4ztHf1aaZ4j8/2JKfALOPSaF8/+MYTpTBA9M0CK08YzdbIWp8P4gSo3GLiqlVr1ZCnqb7jlB5GrCxuWYXqO3CwjfLB12evjsbcDBB4oI8sFtiFxFomBU2RXyu+rnBmE84qH+D7jq1TxMmVIxm7no8cD+Q99KIRn47ruNtqkj2FN6/6ZILWxGE4LSvaN4kIvWerpoZy8o3IUP4iOU8en7YwqE3Tl6Ywl3qBuA+cHV9YnKloSLMRxqKdVKbifEiGbwg+N4/DLYQesWsn8VnE7u2IEBzPtknjZSmC88RnJBrx71Y5W9FzXfNWAZ1KuZufSInAkL0EZrkuUxwtVjIgQ+WuDF/mHaUjtVIifLWQ6UqNwwQ1sLa0Mpw7gMTiOYszDayaoaswULbEoqruZ7/8OeIN8jcjiUptUnIiXLP+0Jn7Pd/M0V0dnIW7DXKYoyUPE4L+j9C/xNuHBlBksu/FFh4Et/E4Fa1ZuU5c2Aj1s68FZ27QpFefCzicaOmx9NLBh2TqSUBKuy1mBC8E= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: f0b5a134-9829-47ff-9067-08dcc3b48707 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Aug 2024 20:45:30.8455 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8d891be1-7bce-4216-9a99-bee9de02ba58 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 6KkrkFVGl7+iXUgYppqYhZyhdZOjqShTAnO0cZkrChvamMe6/+DwiFAyy25jTZdu2kDK1YJJQ7Ykl5YlWZsZylCRjdHpnIgfIuNGgthKkGE= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB11224 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean no functional changes Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- include/net/tcp.h | 37 +++++++- net/net.c | 11 ++- net/tcp.c | 231 +++++++++++++++++++++++----------------------- net/wget.c | 3 +- 4 files changed, 163 insertions(+), 119 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index c29d4ce24a7..14aee64cb1c 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -277,9 +277,40 @@ enum tcp_state { TCP_FIN_WAIT_2 }; -enum tcp_state tcp_get_tcp_state(void); -void tcp_set_tcp_state(enum tcp_state new_state); -int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, +/** + * struct tcp_stream - TCP data stream structure + * + * @state: TCP connection state + * + * @seq_init: Initial receive sequence number + * @ack_edge: Receive next + * + * @loc_timestamp: Local timestamp + * @rmt_timestamp: Remote timestamp + * + * @lost: Used for SACK + */ +struct tcp_stream { + /* TCP connection state */ + enum tcp_state state; + + u32 seq_init; + u32 ack_edge; + + /* TCP option timestamp */ + u32 loc_timestamp; + u32 rmt_timestamp; + + /* TCP sliding window control used to request re-TX */ + struct tcp_sack_v lost; +}; + +struct tcp_stream *tcp_stream_get(void); + +enum tcp_state tcp_get_tcp_state(struct tcp_stream *tcp); +void tcp_set_tcp_state(struct tcp_stream *tcp, enum tcp_state new_state); +int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, + int sport, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num); /** diff --git a/net/net.c b/net/net.c index d9bc9df643f..6c5ee7e0925 100644 --- a/net/net.c +++ b/net/net.c @@ -414,7 +414,7 @@ int net_init(void) /* Only need to setup buffer pointers once. */ first_call = 0; if (IS_ENABLED(CONFIG_PROT_TCP)) - tcp_set_tcp_state(TCP_CLOSED); + tcp_set_tcp_state(tcp_stream_get(), TCP_CLOSED); } return net_init_loop(); @@ -915,6 +915,9 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, uchar *pkt; int eth_hdr_size; int pkt_hdr_size; +#if defined(CONFIG_PROT_TCP) + struct tcp_stream *tcp; +#endif /* make sure the net_tx_packet is initialized (net_init() was called) */ assert(net_tx_packet != NULL); @@ -941,8 +944,12 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, break; #if defined(CONFIG_PROT_TCP) case IPPROTO_TCP: + tcp = tcp_stream_get(); + if (tcp == NULL) + return -EINVAL; + pkt_hdr_size = eth_hdr_size - + tcp_set_tcp_header(pkt + eth_hdr_size, dport, sport, + + tcp_set_tcp_header(tcp, pkt + eth_hdr_size, dport, sport, payload_len, action, tcp_seq_num, tcp_ack_num); break; diff --git a/net/tcp.c b/net/tcp.c index 724536cb352..6646f171b83 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -24,19 +24,8 @@ #include #include -/* - * TCP sliding window control used by us to request re-TX - */ -static struct tcp_sack_v tcp_lost; - -/* TCP option timestamp */ -static u32 loc_timestamp; -static u32 rmt_timestamp; - -static u32 tcp_seq_init; -static u32 tcp_ack_edge; - static int tcp_activity_count; +static struct tcp_stream tcp_stream; /* * TCP lengths are stored as a rounded up number of 32 bit words. @@ -48,9 +37,6 @@ static int tcp_activity_count; #define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4) #define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2) -/* TCP connection state */ -static enum tcp_state current_tcp_state; - /* Current TCP RX packet handler */ static rxhand_tcp *tcp_packet_handler; @@ -60,22 +46,30 @@ static inline s32 tcp_seq_cmp(u32 a, u32 b) } /** - * tcp_get_tcp_state() - get current TCP state + * tcp_get_tcp_state() - get TCP stream state + * @tcp: tcp stream * - * Return: Current TCP state + * Return: TCP stream state */ -enum tcp_state tcp_get_tcp_state(void) +enum tcp_state tcp_get_tcp_state(struct tcp_stream *tcp) { - return current_tcp_state; + return tcp->state; } /** - * tcp_set_tcp_state() - set current TCP state + * tcp_set_tcp_state() - set TCP stream state + * @tcp: tcp stream * @new_state: new TCP state */ -void tcp_set_tcp_state(enum tcp_state new_state) +void tcp_set_tcp_state(struct tcp_stream *tcp, + enum tcp_state new_state) { - current_tcp_state = new_state; + tcp->state = new_state; +} + +struct tcp_stream *tcp_stream_get(void) +{ + return &tcp_stream; } static void dummy_handler(uchar *pkt, u16 dport, @@ -138,29 +132,30 @@ u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, struct in_addr dest, /** * net_set_ack_options() - set TCP options in acknowledge packets + * @tcp: tcp stream * @b: the packet * * Return: TCP header length */ -int net_set_ack_options(union tcp_build_pkt *b) +int net_set_ack_options(struct tcp_stream *tcp, union tcp_build_pkt *b) { b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); b->sack.t_opt.kind = TCP_O_TS; b->sack.t_opt.len = TCP_OPT_LEN_A; - b->sack.t_opt.t_snd = htons(loc_timestamp); - b->sack.t_opt.t_rcv = rmt_timestamp; + b->sack.t_opt.t_snd = htons(tcp->loc_timestamp); + b->sack.t_opt.t_rcv = tcp->rmt_timestamp; b->sack.sack_v.kind = TCP_1_NOP; b->sack.sack_v.len = 0; if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) { - if (tcp_lost.len > TCP_OPT_LEN_2) { + if (tcp->lost.len > TCP_OPT_LEN_2) { debug_cond(DEBUG_DEV_PKT, "TCP ack opt lost.len %x\n", - tcp_lost.len); - b->sack.sack_v.len = tcp_lost.len; + tcp->lost.len); + b->sack.sack_v.len = tcp->lost.len; b->sack.sack_v.kind = TCP_V_SACK; - b->sack.sack_v.hill[0].l = htonl(tcp_lost.hill[0].l); - b->sack.sack_v.hill[0].r = htonl(tcp_lost.hill[0].r); + b->sack.sack_v.hill[0].l = htonl(tcp->lost.hill[0].l); + b->sack.sack_v.hill[0].r = htonl(tcp->lost.hill[0].r); /* * These SACK structures are initialized with NOPs to @@ -168,17 +163,17 @@ int net_set_ack_options(union tcp_build_pkt *b) * SACK structures used for both header padding and * internally. */ - b->sack.sack_v.hill[1].l = htonl(tcp_lost.hill[1].l); - b->sack.sack_v.hill[1].r = htonl(tcp_lost.hill[1].r); - b->sack.sack_v.hill[2].l = htonl(tcp_lost.hill[2].l); - b->sack.sack_v.hill[2].r = htonl(tcp_lost.hill[2].r); + b->sack.sack_v.hill[1].l = htonl(tcp->lost.hill[1].l); + b->sack.sack_v.hill[1].r = htonl(tcp->lost.hill[1].r); + b->sack.sack_v.hill[2].l = htonl(tcp->lost.hill[2].l); + b->sack.sack_v.hill[2].r = htonl(tcp->lost.hill[2].r); b->sack.sack_v.hill[3].l = TCP_O_NOP; b->sack.sack_v.hill[3].r = TCP_O_NOP; } b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + TCP_TSOPT_SIZE + - tcp_lost.len)); + tcp->lost.len)); } else { b->sack.sack_v.kind = 0; b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + @@ -194,13 +189,14 @@ int net_set_ack_options(union tcp_build_pkt *b) } /** - * net_set_ack_options() - set TCP options in SYN packets + * net_set_syn_options() - set TCP options in SYN packets + * @tcp: tcp stream * @b: the packet */ -void net_set_syn_options(union tcp_build_pkt *b) +void net_set_syn_options(struct tcp_stream *tcp, union tcp_build_pkt *b) { if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) - tcp_lost.len = 0; + tcp->lost.len = 0; b->ip.hdr.tcp_hlen = 0xa0; @@ -219,14 +215,15 @@ void net_set_syn_options(union tcp_build_pkt *b) } b->ip.t_opt.kind = TCP_O_TS; b->ip.t_opt.len = TCP_OPT_LEN_A; - loc_timestamp = get_ticks(); - rmt_timestamp = 0; + tcp->loc_timestamp = get_ticks(); + tcp->rmt_timestamp = 0; b->ip.t_opt.t_snd = 0; b->ip.t_opt.t_rcv = 0; b->ip.end = TCP_O_END; } -int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, +int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, + int sport, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num) { union tcp_build_pkt *b = (union tcp_build_pkt *)pkt; @@ -249,21 +246,21 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); tcp_activity_count = 0; - net_set_syn_options(b); + net_set_syn_options(tcp, b); tcp_seq_num = 0; tcp_ack_num = 0; pkt_hdr_len = IP_TCP_O_SIZE; - if (current_tcp_state == TCP_SYN_SENT) { /* Too many SYNs */ + if (tcp->state == TCP_SYN_SENT) { /* Too many SYNs */ action = TCP_FIN; - current_tcp_state = TCP_FIN_WAIT_1; + tcp->state = TCP_FIN_WAIT_1; } else { - tcp_lost.len = TCP_OPT_LEN_2; - current_tcp_state = TCP_SYN_SENT; + tcp->lost.len = TCP_OPT_LEN_2; + tcp->state = TCP_SYN_SENT; } break; case TCP_SYN | TCP_ACK: case TCP_ACK: - pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(b); + pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(tcp, b); b->ip.hdr.tcp_flags = action; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:ACK (%pI4, %pI4, s=%u, a=%u, A=%x)\n", @@ -276,20 +273,20 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); payload_len = 0; pkt_hdr_len = IP_TCP_HDR_SIZE; - current_tcp_state = TCP_FIN_WAIT_1; + tcp->state = TCP_FIN_WAIT_1; break; case TCP_RST | TCP_ACK: case TCP_RST: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:RST (%pI4, %pI4, s=%u, a=%u)\n", &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; break; /* Notify connection closing */ case (TCP_FIN | TCP_ACK): case (TCP_FIN | TCP_ACK | TCP_PUSH): - if (current_tcp_state == TCP_CLOSE_WAIT) - current_tcp_state = TCP_CLOSING; + if (tcp->state == TCP_CLOSE_WAIT) + tcp->state = TCP_CLOSING; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%u, a=%u, A=%x)\n", @@ -297,7 +294,7 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, tcp_seq_num, tcp_ack_num, action); fallthrough; default: - pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(b); + pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(tcp, b); b->ip.hdr.tcp_flags = action | TCP_PUSH | TCP_ACK; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:dft (%pI4, %pI4, s=%u, a=%u, A=%x)\n", @@ -308,9 +305,9 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, pkt_len = pkt_hdr_len + payload_len; tcp_len = pkt_len - IP_HDR_SIZE; - tcp_ack_edge = tcp_ack_num; + tcp->ack_edge = tcp_ack_num; /* TCP Header */ - b->ip.hdr.tcp_ack = htonl(tcp_ack_edge); + b->ip.hdr.tcp_ack = htonl(tcp->ack_edge); b->ip.hdr.tcp_src = htons(sport); b->ip.hdr.tcp_dst = htons(dport); b->ip.hdr.tcp_seq = htonl(tcp_seq_num); @@ -344,78 +341,79 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, return pkt_hdr_len; } -static void tcp_update_ack_edge(void) +static void tcp_update_ack_edge(struct tcp_stream *tcp) { - if (tcp_seq_cmp(tcp_ack_edge, tcp_lost.hill[0].l) >= 0) { - tcp_ack_edge = tcp_lost.hill[0].r; + if (tcp_seq_cmp(tcp->ack_edge, tcp->lost.hill[0].l) >= 0) { + tcp->ack_edge = tcp->lost.hill[0].r; - memmove(&tcp_lost.hill[0], &tcp_lost.hill[1], + memmove(&tcp->lost.hill[0], &tcp->lost.hill[1], (TCP_SACK_HILLS - 1) * sizeof(struct sack_edges)); - tcp_lost.len -= TCP_OPT_LEN_8; - tcp_lost.hill[TCP_SACK_HILLS - 1].l = TCP_O_NOP; - tcp_lost.hill[TCP_SACK_HILLS - 1].r = TCP_O_NOP; + tcp->lost.len -= TCP_OPT_LEN_8; + tcp->lost.hill[TCP_SACK_HILLS - 1].l = TCP_O_NOP; + tcp->lost.hill[TCP_SACK_HILLS - 1].r = TCP_O_NOP; } } /** * tcp_hole() - Selective Acknowledgment (Essential for fast stream transfer) + * @tcp: tcp stream * @tcp_seq_num: TCP sequence start number * @len: the length of sequence numbers */ -void tcp_hole(u32 tcp_seq_num, u32 len) +void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) { int i, j, cnt, cnt_move; - cnt = (tcp_lost.len - TCP_OPT_LEN_2) / TCP_OPT_LEN_8; + cnt = (tcp->lost.len - TCP_OPT_LEN_2) / TCP_OPT_LEN_8; for (i = 0; i < cnt; i++) { - if (tcp_seq_cmp(tcp_lost.hill[i].r, tcp_seq_num) < 0) + if (tcp_seq_cmp(tcp->lost.hill[i].r, tcp_seq_num) < 0) continue; - if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num + len) > 0) + if (tcp_seq_cmp(tcp->lost.hill[i].l, tcp_seq_num + len) > 0) break; - if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num) > 0) - tcp_lost.hill[i].l = tcp_seq_num; - if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num) < 0) { - len += tcp_seq_num - tcp_lost.hill[i].l; - tcp_seq_num = tcp_lost.hill[i].l; + if (tcp_seq_cmp(tcp->lost.hill[i].l, tcp_seq_num) > 0) + tcp->lost.hill[i].l = tcp_seq_num; + if (tcp_seq_cmp(tcp->lost.hill[i].l, tcp_seq_num) < 0) { + len += tcp_seq_num - tcp->lost.hill[i].l; + tcp_seq_num = tcp->lost.hill[i].l; } - if (tcp_seq_cmp(tcp_lost.hill[i].r, tcp_seq_num + len) >= 0) { - tcp_update_ack_edge(); + if (tcp_seq_cmp(tcp->lost.hill[i].r, tcp_seq_num + len) >= 0) { + tcp_update_ack_edge(tcp); return; } /* check overlapping with next hills */ cnt_move = 0; - tcp_lost.hill[i].r = tcp_seq_num + len; + tcp->lost.hill[i].r = tcp_seq_num + len; for (j = i + 1; j < cnt; j++) { - if (tcp_seq_cmp(tcp_lost.hill[j].l, tcp_lost.hill[i].r) > 0) + if (tcp_seq_cmp(tcp->lost.hill[j].l, tcp->lost.hill[i].r) > 0) break; - tcp_lost.hill[i].r = tcp_lost.hill[j].r; + tcp->lost.hill[i].r = tcp->lost.hill[j].r; cnt_move++; } if (cnt_move > 0) { if (cnt > i + cnt_move + 1) - memmove(&tcp_lost.hill[i + 1], - &tcp_lost.hill[i + cnt_move + 1], + memmove(&tcp->lost.hill[i + 1], + &tcp->lost.hill[i + cnt_move + 1], cnt_move * sizeof(struct sack_edges)); cnt -= cnt_move; - tcp_lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; + tcp->lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; for (j = cnt; j < TCP_SACK_HILLS; j++) { - tcp_lost.hill[j].l = TCP_O_NOP; - tcp_lost.hill[j].r = TCP_O_NOP; + tcp->lost.hill[j].l = TCP_O_NOP; + tcp->lost.hill[j].r = TCP_O_NOP; } } - tcp_update_ack_edge(); + tcp_update_ack_edge(tcp); return; } if (i == TCP_SACK_HILLS) { - tcp_update_ack_edge(); + tcp_update_ack_edge(tcp); return; } @@ -428,23 +426,24 @@ void tcp_hole(u32 tcp_seq_num, u32 len) } if (cnt_move > 0) - memmove(&tcp_lost.hill[i + 1], - &tcp_lost.hill[i], + memmove(&tcp->lost.hill[i + 1], + &tcp->lost.hill[i], cnt_move * sizeof(struct sack_edges)); - tcp_lost.hill[i].l = tcp_seq_num; - tcp_lost.hill[i].r = tcp_seq_num + len; - tcp_lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; + tcp->lost.hill[i].l = tcp_seq_num; + tcp->lost.hill[i].r = tcp_seq_num + len; + tcp->lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; - tcp_update_ack_edge(); + tcp_update_ack_edge(tcp); }; /** * tcp_parse_options() - parsing TCP options + * @tcp: tcp stream * @o: pointer to the option field. * @o_len: length of the option field. */ -void tcp_parse_options(uchar *o, int o_len) +void tcp_parse_options(struct tcp_stream *tcp, uchar *o, int o_len) { struct tcp_t_opt *tsopt; uchar *p = o; @@ -467,7 +466,7 @@ void tcp_parse_options(uchar *o, int o_len) break; case TCP_O_TS: tsopt = (struct tcp_t_opt *)p; - rmt_timestamp = tsopt->t_snd; + tcp->rmt_timestamp = tsopt->t_snd; break; } @@ -479,7 +478,8 @@ void tcp_parse_options(uchar *o, int o_len) } } -static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) +static u8 tcp_state_machine(struct tcp_stream *tcp, u8 tcp_flags, + u32 tcp_seq_num, int payload_len) { u8 tcp_fin = tcp_flags & TCP_FIN; u8 tcp_syn = tcp_flags & TCP_SYN; @@ -500,21 +500,21 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) debug_cond(DEBUG_INT_STATE, "TCP STATE ENTRY %x\n", action); if (tcp_rst) { action = TCP_DATA; - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; net_set_state(NETLOOP_FAIL); debug_cond(DEBUG_INT_STATE, "TCP Reset %x\n", tcp_flags); return TCP_RST; } - switch (current_tcp_state) { + switch (tcp->state) { case TCP_CLOSED: debug_cond(DEBUG_INT_STATE, "TCP CLOSED %x\n", tcp_flags); if (tcp_syn) { action = TCP_SYN | TCP_ACK; - tcp_seq_init = tcp_seq_num; - tcp_ack_edge = tcp_seq_num + 1; - tcp_lost.len = TCP_OPT_LEN_2; - current_tcp_state = TCP_SYN_RECEIVED; + tcp->seq_init = tcp_seq_num; + tcp->ack_edge = tcp_seq_num + 1; + tcp->lost.len = TCP_OPT_LEN_2; + tcp->state = TCP_SYN_RECEIVED; } else if (tcp_ack || tcp_fin) { action = TCP_DATA; } @@ -525,12 +525,12 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) tcp_flags, tcp_seq_num); if (tcp_fin) { action = action | TCP_PUSH; - current_tcp_state = TCP_CLOSE_WAIT; + tcp->state = TCP_CLOSE_WAIT; } else if (tcp_ack || (tcp_syn && tcp_ack)) { action |= TCP_ACK; - tcp_seq_init = tcp_seq_num; - tcp_ack_edge = tcp_seq_num + 1; - current_tcp_state = TCP_ESTABLISHED; + tcp->seq_init = tcp_seq_num; + tcp->ack_edge = tcp_seq_num + 1; + tcp->state = TCP_ESTABLISHED; if (tcp_syn && tcp_ack) action |= TCP_PUSH; @@ -541,15 +541,15 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) case TCP_ESTABLISHED: debug_cond(DEBUG_INT_STATE, "TCP_ESTABLISHED %x\n", tcp_flags); if (payload_len > 0) { - tcp_hole(tcp_seq_num, payload_len); + tcp_hole(tcp, tcp_seq_num, payload_len); tcp_fin = TCP_DATA; /* cause standalone FIN */ } if ((tcp_fin) && (!IS_ENABLED(CONFIG_PROT_TCP_SACK) || - tcp_lost.len <= TCP_OPT_LEN_2)) { + tcp->lost.len <= TCP_OPT_LEN_2)) { action = action | TCP_FIN | TCP_PUSH | TCP_ACK; - current_tcp_state = TCP_CLOSE_WAIT; + tcp->state = TCP_CLOSE_WAIT; } else if (tcp_ack) { action = TCP_DATA; } @@ -567,7 +567,7 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_2 (%x)\n", tcp_flags); if (tcp_ack) { action = TCP_PUSH | TCP_ACK; - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; puts("\n"); } else if (tcp_syn) { action = TCP_DATA; @@ -578,20 +578,20 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) case TCP_FIN_WAIT_1: debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_1 (%x)\n", tcp_flags); if (tcp_fin) { - tcp_ack_edge++; + tcp->ack_edge++; action = TCP_ACK | TCP_FIN; - current_tcp_state = TCP_FIN_WAIT_2; + tcp->state = TCP_FIN_WAIT_2; } if (tcp_syn) action = TCP_RST; if (tcp_ack) - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; break; case TCP_CLOSING: debug_cond(DEBUG_INT_STATE, "TCP_CLOSING (%x)\n", tcp_flags); if (tcp_ack) { action = TCP_PUSH; - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; puts("\n"); } else if (tcp_syn) { action = TCP_RST; @@ -615,6 +615,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) u8 tcp_action = TCP_DATA; u32 tcp_seq_num, tcp_ack_num; int tcp_hdr_len, payload_len; + struct tcp_stream *tcp; /* Verify IP header */ debug_cond(DEBUG_DEV_PKT, @@ -643,11 +644,15 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) return; } + tcp = tcp_stream_get(); + if (tcp == NULL) + return; + tcp_hdr_len = GET_TCP_HDR_LEN_IN_BYTES(b->ip.hdr.tcp_hlen); payload_len = tcp_len - tcp_hdr_len; if (tcp_hdr_len > TCP_HDR_SIZE) - tcp_parse_options((uchar *)b + IP_TCP_HDR_SIZE, + tcp_parse_options(tcp, (uchar *)b + IP_TCP_HDR_SIZE, tcp_hdr_len - TCP_HDR_SIZE); /* * Incoming sequence and ack numbers are server's view of the numbers. @@ -657,7 +662,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) tcp_ack_num = ntohl(b->ip.hdr.tcp_ack); /* Packets are not ordered. Send to app as received. */ - tcp_action = tcp_state_machine(b->ip.hdr.tcp_flags, + tcp_action = tcp_state_machine(tcp, b->ip.hdr.tcp_flags, tcp_seq_num, payload_len); tcp_activity_count++; @@ -678,7 +683,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) } else if (tcp_action != TCP_DATA) { debug_cond(DEBUG_DEV_PKT, "TCP Action (action=%x,Seq=%u,Ack=%u,Pay=%d)\n", - tcp_action, tcp_ack_num, tcp_ack_edge, payload_len); + tcp_action, tcp_ack_num, tcp->ack_edge, payload_len); /* * Warning: Incoming Ack & Seq sequence numbers are transposed @@ -687,6 +692,6 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) net_send_tcp_packet(0, ntohs(b->ip.hdr.tcp_src), ntohs(b->ip.hdr.tcp_dst), (tcp_action & (~TCP_PUSH)), - tcp_ack_num, tcp_ack_edge); + tcp_ack_num, tcp->ack_edge); } } diff --git a/net/wget.c b/net/wget.c index f1dd7abeff6..c0a80597bfe 100644 --- a/net/wget.c +++ b/net/wget.c @@ -356,7 +356,8 @@ static void wget_handler(uchar *pkt, u16 dport, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len) { - enum tcp_state wget_tcp_state = tcp_get_tcp_state(); + struct tcp_stream *tcp = tcp_stream_get(); + enum tcp_state wget_tcp_state = tcp_get_tcp_state(tcp); net_set_timeout_handler(wget_timeout, wget_timeout_handler); packets++; From patchwork Fri Aug 23 20:45:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1976258 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=pjgd94c4; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WrBtp4LZ0z1yXY for ; Sat, 24 Aug 2024 06:46:26 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D4FA788C29; Fri, 23 Aug 2024 22:45:40 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b="pjgd94c4"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 30D4B88BF2; Fri, 23 Aug 2024 22:45:37 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS,T_FILL_THIS_FORM_SHORT,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-VI1-obe.outbound.protection.outlook.com (mail-vi1eur02on2070c.outbound.protection.outlook.com [IPv6:2a01:111:f403:2607::70c]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 8DC7488936 for ; Fri, 23 Aug 2024 22:45:33 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=gs76GF7w8p42/Dx20r/QxrNR64kZUs6SLLWuiayhFIgv9ePMwzHc8kfrtWtoQtAnOp/DTtc6bgYtmsmnI1QCUCkyUxNM+XxfifZfstYYs5sRhbkc/DLInBgaBN3lfTNpso39OlJqeZsckzCTI6xuUbp0erza+qGxnu9PiGt5KvAFaHf88E3Fz0Va8JfNxzOOAJuGyJExefGz3aWaL58qJv8bUMoGvRIrspFFEiUNVKq9HRHeDSaTbLbcsVvsbiA/JmuACqP1uCN0mlciBbQi8Qc44e2kFaVzMtaioGb/X2L6Q9RYXT5+xjvBOQ+E+6oMlTxqZijhLInVKOeUedbXnw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=uQUQRxuC7ZRfmrgfQKZZ0S7oLJ9R/9eQQNAuk0enCMk=; b=g8mJ+5zp+jm6DtmqWmBk4xaSe3lRpWeG7LJgBpcyOnMZywEwLkWz8lhqHPIhVhAOISiSV4F4v231lN/zpkjP1HSzHD/GIMg9jz5273nBX0xomY4tFgUU+13mH+502NnJDYBHcGi5TU0nAK005glDeTcEiXNNJJmiATL09FJtS9xYaqCPn74KnfKRr7r/6oqk9rmch1D8d4KaHWiW5kz72lPXR3hOq6uesj2Z3SfVXOCG/4YKbAJjsAgMZHrjXtYlR5ecRQ9ND9keayfLPbarEDiCvsBRaJINrPs+tq00kVi14ij9nFPnnSDQ7cY8JmSrl9eY9R4Lo2Hdb4HCSw0CAg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu; dkim=pass header.d=iopsys.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uQUQRxuC7ZRfmrgfQKZZ0S7oLJ9R/9eQQNAuk0enCMk=; b=pjgd94c4Wq2z2AyFugUz6WRIRxocmhyxv6+xGEWugYfJBN2zzwZbwSwCoM5r0A1aIr0++cDAe3m0wmaFpVcW7jPDiAtSMQfyueV4G/SaV7LD7wte65X89FHDGGu6Yju5pLQJKfX3/oc2srMKbyksgncpRJbRG9qGJEys2YgovdcQ/Si4HRUqqEKsdzHmBkm64ie39r2fPnXMS0+DvWG2illMPJGPmd04K6tsMk+oXnQPmalwwcT/1lV6434ZeWf33B7fG0cK68286pKkuvPmQioLXc4UT4o3gmYLJeSEDpnC0TSOhVftFUtvWuT3tw4XvAJ3qw20HxHpcwXbzbA8dQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=iopsys.eu; Received: from GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) by VI0PR08MB11224.eurprd08.prod.outlook.com (2603:10a6:800:251::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.12; Fri, 23 Aug 2024 20:45:32 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7897.010; Fri, 23 Aug 2024 20:45:32 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Yasuharu Shibata , u-boot@lists.denx.de Subject: [PATCH v4 4/9] net/tcp: add connection info to tcp_stream structure Date: Fri, 23 Aug 2024 23:45:13 +0300 Message-ID: <20240823204518.1010194-5-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> References: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR4P281CA0373.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f8::20) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB11224:EE_ X-MS-Office365-Filtering-Correlation-Id: 462e3598-7d59-4989-5c2c-08dcc3b487cd X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|7416014|52116014|376014|1800799024|38350700014|921020; X-Microsoft-Antispam-Message-Info: 9ORYLMcXHnJZgXgjlKmhdwlY9x05fdZF/jwtwR8CzaQb2KCoOmrS+Ml/xqEQz6QFWzckHhCjeW9oWmuVjiXD8eorqoxC34iPEmW7Xew1LLZgnOE4V8iJ0jCwNVFQIQNLZs5J5EUWxT6FPmMM93FvZ+klk+CYTRMpKC9jvIqR94RsVH/DRAUzAzTKsdbaOIL1W/MOEYLA7JetQ1LeD2ZATwrln9dw0xsYsfEjRE25qLDwQxY6TtDZdS209N4N4S9vBfNLElFpCy+eNxSCuRn3DMbOKKqN7HDLn+YfaY/dGLwbUI7FF7AF15zDDeJUD11tAOJMR9LW8q4Bst5pixZLHvv8YVrWJ7QxJA6AOkkgqAIwnhA0WMAJI2eiIhrW42TBGsAf+1wzD9k58kHZJL6xVueWC8lARVUwSR7+icvdfPVWfBMafM1ng55PZ8ZjLbAkFhEXkzukWBHGcZW8Eifr29MMX5VlUSrPM2xrwVoWbyobdaTZpMqVSvPCYbtbIdZLrH0sYQJdjx5x3ZnuSWwcvlxWzPvpf1nzS7n61IjqpACrcM+Y/bBAKUX+bffWTnz9Y/0W2H0G91jqBd+l+YHJvhZgdl29dI8LiVs/tEhTLfjTIhMn/piRMJvhZhyhVFUei8957P3w/3nXGu4G/lQ6qGIb4rge28UnVLyOp4Ws0k1leFtjyy/dDMPsOGBN7/xikfGMpMIGYRANVCu/FS9g7O9yx3Y05WKKk17q60hyg2ndRx5GA8gWgwYgHp/6akXap9wXhlsCKouAA0LNxSq5lRsrLDJIFZyUqlNQpa8egDR7wdEKn8My7f8LKF90rBvSRHLL/xajQooQLAMxfu9HR4Tx8MPyVrJt+9wonU/9KKkSfcmTTVYsb68uoFRBvJlAhCqOyUeJXDAKTSzOF8rMzO0hsOI8psCruk4SdAH388Xp7h3kCa8xu6uZK3bslnrSPe5dJiFW3pYaThDkAV8buKKcAB2tcsuYYpegD6rvjvYsTGKfKH+6uk9FUxMuHgFJiYF0rKpE9pHV3mdXgz6FTUL6D0Ak2AsQuwAgIMBrEYks//cRtS6CeUwm/fjJxfwftoYX43TFhVoB3oQ1ZbDCtwlxYtwMo81GQm+qCmKqu1OyWFEoUjsgEKKAbF/zf0+bMa5AYgZ8pT7AUOC4B3izbAaWN/K6Ad8eBgzCgKB0arHlanugwFmDevFSK/E8oO6AKDRrbIQx9rqdBNe82pvI0nYv4Ko+Wa9TEOuiD4xNk2HGjLT9NYhrOw51KdT/Efy/dscnOQQccY83VCyWJCWKKRuoVazzVVcdXtSR5K640gEYHaRR+jT0c+StUl9lM9mk58Q3XbRr3G/XIiLSXWHLvM9APEdh7Jo4F1OrxKkFZ+h/epHW828Rt9ch0p4yCnJFnFLF6fetrliy4ctmafSpXPeasgG/puK2ltYzYZgw5go= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(7416014)(52116014)(376014)(1800799024)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: AvWE2qpbRUTTfq0ITtxus5711cTDjWcGfy/SrHekVq2/xJIWOhYjY2bGeUgpq8SSOC5Emu/+mWdh6yjDw2DssGN4mOov8Il9XBGQZASNQRhdIqP7uKeImaQV8R9h27McML5xGIAkvTltad66ahDTt05ulF69UC09A6nZhzOa4kbDPlon6yNUKDrZbuRh+tmrHF7XobItRA6tMfdR5Nk4FpBaZrViUAgieKv2Lt9rtwAF2ESjiwUh0JC6dyETwBt1Pp91Q0RhMqez4QAVHb7Gd/cf3WXogPHJeKbkeCUtxrhg/835PQkbc5eovixm2IdAXo7JC1t9vLU3Frdge5bEbwVyXfjiEjZZ0E46fOombbqpAnz0pe5bqAFNFyJJOGeuKHMHWTRsPRL7zp+nyO6pfz3f4+TWV1TJrTs443fr0ut41+iKGJuTvg2rz6On4Ie1a5SQ9caE6QrUuQ/D5tlnpWH88ioQxht3x4ZjmAzIiq5ZUP45IkZFC83b7bLG3YQiCZ+pmvkWVKGJvImnq/yQm4c5UzZd5+VFutexCA+5uiglYFFXxLi1NvQ9l1txfrL2QB/BwAsHsUSASmI12ilOsaTeFfQCb7HTIqQILPvKOVZW0OmQZhSs/MU28/WKzLGIZUCBBYe8AVHjhouu7v+Pg5MG9BFWSVUbQff5+Un9Du+GW77h8Nui0aocvInC/phe0DXBud7if8zufbE3B1/Yu3mdoLtMeWUeAGBf1pKIn/fcEklqN3G72sYBokoqU9+LMY4Nf/Pa+ZvVHthzgiADBXps9pKCfNdwH8qVrU2zgzPWx3a2kchkAhbIJTebDubtT7CFQ/R6zbqLxIe2HTvu8SGMOeIOEK7wquV/oEZpE807dUg72Sa2LpSqyk4mlImBd/54QQ1Bk0OUbNHyZ7jfzA7xZPerLFLMu2SaOLZJTmw5Fmll4DbopHoAoFD7UUnL/Ok9B6NN65SNsNozYmGXCIFuANFQL7BHQmmwxvBZqmQtMaj4FwULycIzQvJov6SAIfy3eq9TC6AXECEteRV+7YegbZD1Wm2kqDzPBBR8VCt/E0J6wmaJnRshErHt+83/k6xeMyzCrDhtpGXDFGxdzlLcGeBy+PskO08vwMEOu3lUXtYpf6NBdAfXAzACaPNCnlNNf8BQXfM8AaffZPlgGr6aQ7wQXZvai0x9LjtEbjsDKD6DBF17Sb9fUlkAzTi7tdXOYwA25Yle+nwDvBHhjsjsX4kB1WEDxNJDgKCXrjsm+4qUU0/k8oXrJjy2Hq56v9/rlKq78AWwg43hWeXY2v0NgBGgxR42FG+q2HhkuYqFrUE5ROJVLbhjG98xu//6AkrfJDLna63081Zyo3qtxvP5s6pcdN0OWxB5vmQ/1MCF/qv5vJT82MIf3wI3rfE1m3k9HX4yCS/dXJpw4TwjNbY6nejFV72pRW+RkMfvqMhvOwPQj6OtgiYEf43xaAR0301/uf5le43LTH0/zsUyOqibJvSGqCoUxC90gSIG9hxkH1zvp7+vpWtG+pJmYnzZ/gELQ3TabIBTX/Wh7zNVmCrt5ZK2fryqCWr63wB9A2UcaLErApo1q3AFMCf8pc9RFeb2cfgjIWHzThbfhpHdKG4RSNYONpV8xLqIOQqtJvI= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 462e3598-7d59-4989-5c2c-08dcc3b487cd X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Aug 2024 20:45:32.1479 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8d891be1-7bce-4216-9a99-bee9de02ba58 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: TyMYwyvKyvr9LD53HOCszFRXQ/K3gIfRCz27lOCaNqhaq0rJsb2Ou17R+XXM3dTjjoJUP4lgef/9DMd7VoB4d2A+uj0jSF6VILLwPX0U2QQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB11224 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Changes: * Avoid use net_server_ip in tcp code, use tcp_stream data instead * Ignore packets from other connections if connection already created. This prevents us from connection break caused by other tcp stream. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- include/net.h | 5 +- include/net/tcp.h | 57 +++++++++++++++++--- net/fastboot_tcp.c | 46 ++++++++-------- net/net.c | 12 ++--- net/tcp.c | 129 ++++++++++++++++++++++++++++++++++----------- net/wget.c | 52 +++++++----------- 6 files changed, 201 insertions(+), 100 deletions(-) diff --git a/include/net.h b/include/net.h index bb2ae20f52a..b0ce13e0a9d 100644 --- a/include/net.h +++ b/include/net.h @@ -667,6 +667,7 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, /** * net_send_tcp_packet() - Transmit TCP packet. * @payload_len: length of payload + * @dhost: Destination host * @dport: Destination TCP port * @sport: Source TCP port * @action: TCP action to be performed @@ -675,8 +676,8 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, * * Return: 0 on success, other value on failure */ -int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action, - u32 tcp_seq_num, u32 tcp_ack_num); +int net_send_tcp_packet(int payload_len, struct in_addr dhost, int dport, + int sport, u8 action, u32 tcp_seq_num, u32 tcp_ack_num); int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport, int payload_len); diff --git a/include/net/tcp.h b/include/net/tcp.h index 14aee64cb1c..f224d0cae2f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -279,6 +279,9 @@ enum tcp_state { /** * struct tcp_stream - TCP data stream structure + * @rhost: Remote host, network byte order + * @rport: Remote port, host byte order + * @lport: Local port, host byte order * * @state: TCP connection state * @@ -291,6 +294,10 @@ enum tcp_state { * @lost: Used for SACK */ struct tcp_stream { + struct in_addr rhost; + u16 rport; + u16 lport; + /* TCP connection state */ enum tcp_state state; @@ -305,16 +312,53 @@ struct tcp_stream { struct tcp_sack_v lost; }; -struct tcp_stream *tcp_stream_get(void); +void tcp_init(void); + +typedef int tcp_incoming_filter(struct in_addr rhost, + u16 rport, u16 sport); + +/* + * This function sets user callback used to accept/drop incoming + * connections. Callback should: + * + Check TCP stream endpoint and make connection verdict + * - return non-zero value to accept connection + * - return zero to drop connection + * + * WARNING: If callback is NOT defined, all incoming connections + * will be dropped. + */ +void tcp_set_incoming_filter(tcp_incoming_filter *filter); + +/* + * tcp_stream_get -- Get or create TCP stream + * @is_new: if non-zero and no stream found, then create a new one + * @rhost: Remote host, network byte order + * @rport: Remote port, host byte order + * @lport: Local port, host byte order + * + * Returns: TCP stream structure or NULL (if not found/created) + */ +struct tcp_stream *tcp_stream_get(int is_new, struct in_addr rhost, + u16 rport, u16 lport); + +/* + * tcp_stream_connect -- Create new TCP stream for remote connection. + * @rhost: Remote host, network byte order + * @rport: Remote port, host byte order + * + * Returns: TCP new stream structure or NULL (if not created). + * Random local port will be used. + */ +struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport); + +enum tcp_state tcp_stream_get_state(struct tcp_stream *tcp); -enum tcp_state tcp_get_tcp_state(struct tcp_stream *tcp); -void tcp_set_tcp_state(struct tcp_stream *tcp, enum tcp_state new_state); -int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, - int sport, int payload_len, +int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num); /** * rxhand_tcp() - An incoming packet handler. + * @tcp: TCP stream * @pkt: pointer to the application packet * @dport: destination TCP port * @sip: source IP address @@ -324,8 +368,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, * @action: TCP action (SYN, ACK, FIN, etc) * @len: packet length */ -typedef void rxhand_tcp(uchar *pkt, u16 dport, - struct in_addr sip, u16 sport, +typedef void rxhand_tcp(struct tcp_stream *tcp, uchar *pkt, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len); void tcp_set_tcp_handler(rxhand_tcp *f); diff --git a/net/fastboot_tcp.c b/net/fastboot_tcp.c index d1fccbc7238..12a4d6690be 100644 --- a/net/fastboot_tcp.c +++ b/net/fastboot_tcp.c @@ -8,14 +8,14 @@ #include #include +#define FASTBOOT_TCP_PORT 5554 + static char command[FASTBOOT_COMMAND_LEN] = {0}; static char response[FASTBOOT_RESPONSE_LEN] = {0}; static const unsigned short handshake_length = 4; static const uchar *handshake = "FB01"; -static u16 curr_sport; -static u16 curr_dport; static u32 curr_tcp_seq_num; static u32 curr_tcp_ack_num; static unsigned int curr_request_len; @@ -25,34 +25,37 @@ static enum fastboot_tcp_state { FASTBOOT_DISCONNECTING } state = FASTBOOT_CLOSED; -static void fastboot_tcp_answer(u8 action, unsigned int len) +static void fastboot_tcp_answer(struct tcp_stream *tcp, u8 action, + unsigned int len) { const u32 response_seq_num = curr_tcp_ack_num; const u32 response_ack_num = curr_tcp_seq_num + (curr_request_len > 0 ? curr_request_len : 1); - net_send_tcp_packet(len, htons(curr_sport), htons(curr_dport), + net_send_tcp_packet(len, tcp->rhost, tcp->rport, tcp->lport, action, response_seq_num, response_ack_num); } -static void fastboot_tcp_reset(void) +static void fastboot_tcp_reset(struct tcp_stream *tcp) { - fastboot_tcp_answer(TCP_RST, 0); + fastboot_tcp_answer(tcp, TCP_RST, 0); state = FASTBOOT_CLOSED; } -static void fastboot_tcp_send_packet(u8 action, const uchar *data, unsigned int len) +static void fastboot_tcp_send_packet(struct tcp_stream *tcp, u8 action, + const uchar *data, unsigned int len) { uchar *pkt = net_get_async_tx_pkt_buf(); memset(pkt, '\0', PKTSIZE); pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; memcpy(pkt, data, len); - fastboot_tcp_answer(action, len); + fastboot_tcp_answer(tcp, action, len); memset(pkt, '\0', PKTSIZE); } -static void fastboot_tcp_send_message(const char *message, unsigned int len) +static void fastboot_tcp_send_message(struct tcp_stream *tcp, + const char *message, unsigned int len) { __be64 len_be = __cpu_to_be64(len); uchar *pkt = net_get_async_tx_pkt_buf(); @@ -63,12 +66,11 @@ static void fastboot_tcp_send_message(const char *message, unsigned int len) memcpy(pkt, &len_be, 8); pkt += 8; memcpy(pkt, message, len); - fastboot_tcp_answer(TCP_ACK | TCP_PUSH, len + 8); + fastboot_tcp_answer(tcp, TCP_ACK | TCP_PUSH, len + 8); memset(pkt, '\0', PKTSIZE); } -static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, - struct in_addr sip, u16 sport, +static void fastboot_tcp_handler_ipv4(struct tcp_stream *tcp, uchar *pkt, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len) { @@ -77,8 +79,6 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, u8 tcp_fin = action & TCP_FIN; u8 tcp_push = action & TCP_PUSH; - curr_sport = sport; - curr_dport = dport; curr_tcp_seq_num = tcp_seq_num; curr_tcp_ack_num = tcp_ack_num; curr_request_len = len; @@ -89,17 +89,17 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, if (len != handshake_length || strlen(pkt) != handshake_length || memcmp(pkt, handshake, handshake_length) != 0) { - fastboot_tcp_reset(); + fastboot_tcp_reset(tcp); break; } - fastboot_tcp_send_packet(TCP_ACK | TCP_PUSH, + fastboot_tcp_send_packet(tcp, TCP_ACK | TCP_PUSH, handshake, handshake_length); state = FASTBOOT_CONNECTED; } break; case FASTBOOT_CONNECTED: if (tcp_fin) { - fastboot_tcp_answer(TCP_FIN | TCP_ACK, 0); + fastboot_tcp_answer(tcp, TCP_FIN | TCP_ACK, 0); state = FASTBOOT_DISCONNECTING; break; } @@ -111,12 +111,12 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, // Only single packet messages are supported ATM if (strlen(pkt) != command_size) { - fastboot_tcp_reset(); + fastboot_tcp_reset(tcp); break; } strlcpy(command, pkt, len + 1); fastboot_command_id = fastboot_handle_command(command, response); - fastboot_tcp_send_message(response, strlen(response)); + fastboot_tcp_send_message(tcp, response, strlen(response)); fastboot_handle_boot(fastboot_command_id, strncmp("OKAY", response, 4) == 0); } @@ -129,17 +129,21 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, memset(command, 0, FASTBOOT_COMMAND_LEN); memset(response, 0, FASTBOOT_RESPONSE_LEN); - curr_sport = 0; - curr_dport = 0; curr_tcp_seq_num = 0; curr_tcp_ack_num = 0; curr_request_len = 0; } +static int incoming_filter(struct in_addr rhost, u16 rport, u16 lport) +{ + return (lport == FASTBOOT_TCP_PORT); +} + void fastboot_tcp_start_server(void) { printf("Using %s device\n", eth_get_name()); printf("Listening for fastboot command on tcp %pI4\n", &net_ip); + tcp_set_incoming_filter(incoming_filter); tcp_set_tcp_handler(fastboot_tcp_handler_ipv4); } diff --git a/net/net.c b/net/net.c index 6c5ee7e0925..b33ea59a9fa 100644 --- a/net/net.c +++ b/net/net.c @@ -414,7 +414,7 @@ int net_init(void) /* Only need to setup buffer pointers once. */ first_call = 0; if (IS_ENABLED(CONFIG_PROT_TCP)) - tcp_set_tcp_state(tcp_stream_get(), TCP_CLOSED); + tcp_init(); } return net_init_loop(); @@ -899,10 +899,10 @@ int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport, } #if defined(CONFIG_PROT_TCP) -int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action, - u32 tcp_seq_num, u32 tcp_ack_num) +int net_send_tcp_packet(int payload_len, struct in_addr dhost, int dport, + int sport, u8 action, u32 tcp_seq_num, u32 tcp_ack_num) { - return net_send_ip_packet(net_server_ethaddr, net_server_ip, dport, + return net_send_ip_packet(net_server_ethaddr, dhost, dport, sport, payload_len, IPPROTO_TCP, action, tcp_seq_num, tcp_ack_num); } @@ -944,12 +944,12 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, break; #if defined(CONFIG_PROT_TCP) case IPPROTO_TCP: - tcp = tcp_stream_get(); + tcp = tcp_stream_get(0, dest, dport, sport); if (tcp == NULL) return -EINVAL; pkt_hdr_size = eth_hdr_size - + tcp_set_tcp_header(tcp, pkt + eth_hdr_size, dport, sport, + + tcp_set_tcp_header(tcp, pkt + eth_hdr_size, payload_len, action, tcp_seq_num, tcp_ack_num); break; diff --git a/net/tcp.c b/net/tcp.c index 6646f171b83..9acf9f3ccb2 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -26,6 +26,7 @@ static int tcp_activity_count; static struct tcp_stream tcp_stream; +static tcp_incoming_filter *incoming_filter; /* * TCP lengths are stored as a rounded up number of 32 bit words. @@ -40,40 +41,95 @@ static struct tcp_stream tcp_stream; /* Current TCP RX packet handler */ static rxhand_tcp *tcp_packet_handler; +#define RANDOM_PORT_START 1024 +#define RANDOM_PORT_RANGE 0x4000 + +/** + * random_port() - make port a little random (1024-17407) + * + * Return: random port number from 1024 to 17407 + * + * This keeps the math somewhat trivial to compute, and seems to work with + * all supported protocols/clients/servers + */ +static unsigned int random_port(void) +{ + return RANDOM_PORT_START + (get_timer(0) % RANDOM_PORT_RANGE); +} + static inline s32 tcp_seq_cmp(u32 a, u32 b) { return (s32)(a - b); } /** - * tcp_get_tcp_state() - get TCP stream state + * tcp_stream_get_state() - get TCP stream state * @tcp: tcp stream * * Return: TCP stream state */ -enum tcp_state tcp_get_tcp_state(struct tcp_stream *tcp) +enum tcp_state tcp_stream_get_state(struct tcp_stream *tcp) { return tcp->state; } /** - * tcp_set_tcp_state() - set TCP stream state + * tcp_stream_set_state() - set TCP stream state * @tcp: tcp stream * @new_state: new TCP state */ -void tcp_set_tcp_state(struct tcp_stream *tcp, - enum tcp_state new_state) +static void tcp_stream_set_state(struct tcp_stream *tcp, + enum tcp_state new_state) { tcp->state = new_state; } -struct tcp_stream *tcp_stream_get(void) +void tcp_init(void) +{ + incoming_filter = NULL; + tcp_stream.state = TCP_CLOSED; +} + +void tcp_set_incoming_filter(tcp_incoming_filter *filter) +{ + incoming_filter = filter; +} + +static struct tcp_stream *tcp_stream_add(struct in_addr rhost, + u16 rport, u16 lport) +{ + struct tcp_stream *tcp = &tcp_stream; + + if (tcp->state != TCP_CLOSED) + return NULL; + + memset(tcp, 0, sizeof(struct tcp_stream)); + tcp->rhost.s_addr = rhost.s_addr; + tcp->rport = rport; + tcp->lport = lport; + tcp->state = TCP_CLOSED; + tcp->lost.len = TCP_OPT_LEN_2; + return tcp; +} + +struct tcp_stream *tcp_stream_get(int is_new, struct in_addr rhost, + u16 rport, u16 lport) { - return &tcp_stream; + struct tcp_stream *tcp = &tcp_stream; + + if ((tcp->rhost.s_addr == rhost.s_addr) && + (tcp->rport == rport) && + (tcp->lport == lport)) + return tcp; + + if (!is_new || (incoming_filter == NULL) || + !incoming_filter(rhost, rport, lport)) + return NULL; + + return tcp_stream_add(rhost, rport, lport); } -static void dummy_handler(uchar *pkt, u16 dport, - struct in_addr sip, u16 sport, +static void dummy_handler(struct tcp_stream *tcp, uchar *pkt, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len) { @@ -222,8 +278,7 @@ void net_set_syn_options(struct tcp_stream *tcp, union tcp_build_pkt *b) b->ip.end = TCP_O_END; } -int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, - int sport, int payload_len, +int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num) { union tcp_build_pkt *b = (union tcp_build_pkt *)pkt; @@ -243,7 +298,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, case TCP_SYN: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:SYN (%pI4, %pI4, sq=%u, ak=%u)\n", - &net_server_ip, &net_ip, + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); tcp_activity_count = 0; net_set_syn_options(tcp, b); @@ -264,13 +319,13 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, b->ip.hdr.tcp_flags = action; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:ACK (%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num, + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num, action); break; case TCP_FIN: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:FIN (%pI4, %pI4, s=%u, a=%u)\n", - &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); payload_len = 0; pkt_hdr_len = IP_TCP_HDR_SIZE; tcp->state = TCP_FIN_WAIT_1; @@ -279,7 +334,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, case TCP_RST: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:RST (%pI4, %pI4, s=%u, a=%u)\n", - &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); tcp->state = TCP_CLOSED; break; /* Notify connection closing */ @@ -290,7 +345,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, debug_cond(DEBUG_DEV_PKT, "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &net_server_ip, &net_ip, + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num, action); fallthrough; default: @@ -298,7 +353,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, b->ip.hdr.tcp_flags = action | TCP_PUSH | TCP_ACK; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:dft (%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &net_server_ip, &net_ip, + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num, action); } @@ -308,8 +363,8 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, tcp->ack_edge = tcp_ack_num; /* TCP Header */ b->ip.hdr.tcp_ack = htonl(tcp->ack_edge); - b->ip.hdr.tcp_src = htons(sport); - b->ip.hdr.tcp_dst = htons(dport); + b->ip.hdr.tcp_src = htons(tcp->lport); + b->ip.hdr.tcp_dst = htons(tcp->rport); b->ip.hdr.tcp_seq = htonl(tcp_seq_num); /* @@ -332,10 +387,10 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, b->ip.hdr.tcp_xsum = 0; b->ip.hdr.tcp_ugr = 0; - b->ip.hdr.tcp_xsum = tcp_set_pseudo_header(pkt, net_ip, net_server_ip, + b->ip.hdr.tcp_xsum = tcp_set_pseudo_header(pkt, net_ip, tcp->rhost, tcp_len, pkt_len); - net_set_ip_header((uchar *)&b->ip, net_server_ip, net_ip, + net_set_ip_header((uchar *)&b->ip, tcp->rhost, net_ip, pkt_len, IPPROTO_TCP); return pkt_hdr_len; @@ -616,19 +671,26 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) u32 tcp_seq_num, tcp_ack_num; int tcp_hdr_len, payload_len; struct tcp_stream *tcp; + struct in_addr src; /* Verify IP header */ debug_cond(DEBUG_DEV_PKT, "TCP RX in RX Sum (to=%pI4, from=%pI4, len=%d)\n", &b->ip.hdr.ip_src, &b->ip.hdr.ip_dst, pkt_len); - b->ip.hdr.ip_src = net_server_ip; + /* + * src IP address will be destroyed by TCP checksum verification + * algorithm (see tcp_set_pseudo_header()), so remember it before + * it was garbaged. + */ + src.s_addr = b->ip.hdr.ip_src.s_addr; + b->ip.hdr.ip_dst = net_ip; b->ip.hdr.ip_sum = 0; if (tcp_rx_xsum != compute_ip_checksum(b, IP_HDR_SIZE)) { debug_cond(DEBUG_DEV_PKT, "TCP RX IP xSum Error (%pI4, =%pI4, len=%d)\n", - &net_ip, &net_server_ip, pkt_len); + &net_ip, &src, pkt_len); return; } @@ -640,11 +702,14 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) pkt_len)) { debug_cond(DEBUG_DEV_PKT, "TCP RX TCP xSum Error (%pI4, %pI4, len=%d)\n", - &net_ip, &net_server_ip, tcp_len); + &net_ip, &src, tcp_len); return; } - tcp = tcp_stream_get(); + tcp = tcp_stream_get(b->ip.hdr.tcp_flags & TCP_SYN, + src, + ntohs(b->ip.hdr.tcp_src), + ntohs(b->ip.hdr.tcp_dst)); if (tcp == NULL) return; @@ -676,9 +741,9 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) "TCP Notify (action=%x, Seq=%u,Ack=%u,Pay%d)\n", tcp_action, tcp_seq_num, tcp_ack_num, payload_len); - (*tcp_packet_handler) ((uchar *)b + pkt_len - payload_len, b->ip.hdr.tcp_dst, - b->ip.hdr.ip_src, b->ip.hdr.tcp_src, tcp_seq_num, - tcp_ack_num, tcp_action, payload_len); + (*tcp_packet_handler) (tcp, (uchar *)b + pkt_len - payload_len, + tcp_seq_num, tcp_ack_num, tcp_action, + payload_len); } else if (tcp_action != TCP_DATA) { debug_cond(DEBUG_DEV_PKT, @@ -689,9 +754,13 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) * Warning: Incoming Ack & Seq sequence numbers are transposed * here to outgoing Seq & Ack sequence numbers */ - net_send_tcp_packet(0, ntohs(b->ip.hdr.tcp_src), - ntohs(b->ip.hdr.tcp_dst), + net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, (tcp_action & (~TCP_PUSH)), tcp_ack_num, tcp->ack_edge); } } + +struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport) +{ + return tcp_stream_add(rhost, rport, random_port()); +} diff --git a/net/wget.c b/net/wget.c index c0a80597bfe..ad5db21e97e 100644 --- a/net/wget.c +++ b/net/wget.c @@ -27,9 +27,8 @@ static const char http_eom[] = "\r\n\r\n"; static const char http_ok[] = "200"; static const char content_len[] = "Content-Length"; static const char linefeed[] = "\r\n"; -static struct in_addr web_server_ip; -static int our_port; static int wget_timeout_count; +struct tcp_stream *tcp; struct pkt_qd { uchar *pkt; @@ -137,22 +136,19 @@ static void wget_send_stored(void) int len = retry_len; unsigned int tcp_ack_num = retry_tcp_seq_num + (len == 0 ? 1 : len); unsigned int tcp_seq_num = retry_tcp_ack_num; - unsigned int server_port; uchar *ptr, *offset; - server_port = env_get_ulong("httpdstp", 10, SERVER_PORT) & 0xffff; - switch (current_wget_state) { case WGET_CLOSED: debug_cond(DEBUG_WGET, "wget: send SYN\n"); current_wget_state = WGET_CONNECTING; - net_send_tcp_packet(0, server_port, our_port, action, + net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, action, tcp_seq_num, tcp_ack_num); packets = 0; break; case WGET_CONNECTING: pkt_q_idx = 0; - net_send_tcp_packet(0, server_port, our_port, action, + net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, action, tcp_seq_num, tcp_ack_num); ptr = net_tx_packet + net_eth_hdr_size() + @@ -167,14 +163,14 @@ static void wget_send_stored(void) memcpy(offset, &bootfile3, strlen(bootfile3)); offset += strlen(bootfile3); - net_send_tcp_packet((offset - ptr), server_port, our_port, + net_send_tcp_packet((offset - ptr), tcp->rhost, tcp->rport, tcp->lport, TCP_PUSH, tcp_seq_num, tcp_ack_num); current_wget_state = WGET_CONNECTED; break; case WGET_CONNECTED: case WGET_TRANSFERRING: case WGET_TRANSFERRED: - net_send_tcp_packet(0, server_port, our_port, action, + net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, action, tcp_seq_num, tcp_ack_num); break; } @@ -339,10 +335,8 @@ static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, /** * wget_handler() - TCP handler of wget + * @tcp: TCP stream * @pkt: pointer to the application packet - * @dport: destination TCP port - * @sip: source IP address - * @sport: source TCP port * @tcp_seq_num: TCP sequential number * @tcp_ack_num: TCP acknowledgment number * @action: TCP action (SYN, ACK, FIN, etc) @@ -351,13 +345,11 @@ static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, * In the "application push" invocation, the TCP header with all * its information is pointed to by the packet pointer. */ -static void wget_handler(uchar *pkt, u16 dport, - struct in_addr sip, u16 sport, +static void wget_handler(struct tcp_stream *tcp, uchar *pkt, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len) { - struct tcp_stream *tcp = tcp_stream_get(); - enum tcp_state wget_tcp_state = tcp_get_tcp_state(tcp); + enum tcp_state wget_tcp_state = tcp_stream_get_state(tcp); net_set_timeout_handler(wget_timeout, wget_timeout_handler); packets++; @@ -441,26 +433,13 @@ static void wget_handler(uchar *pkt, u16 dport, } } -#define RANDOM_PORT_START 1024 -#define RANDOM_PORT_RANGE 0x4000 - -/** - * random_port() - make port a little random (1024-17407) - * - * Return: random port number from 1024 to 17407 - * - * This keeps the math somewhat trivial to compute, and seems to work with - * all supported protocols/clients/servers - */ -static unsigned int random_port(void) -{ - return RANDOM_PORT_START + (get_timer(0) % RANDOM_PORT_RANGE); -} - #define BLOCKSIZE 512 void wget_start(void) { + struct in_addr web_server_ip; + unsigned int server_port; + image_url = strchr(net_boot_file_name, ':'); if (image_url > 0) { web_server_ip = string_to_ip(net_boot_file_name); @@ -513,8 +492,6 @@ void wget_start(void) wget_timeout_count = 0; current_wget_state = WGET_CLOSED; - our_port = random_port(); - /* * Zero out server ether to force arp resolution in case * the server ip for the previous u-boot command, for example dns @@ -523,6 +500,13 @@ void wget_start(void) memset(net_server_ethaddr, 0, 6); + server_port = env_get_ulong("httpdstp", 10, SERVER_PORT) & 0xffff; + tcp = tcp_stream_connect(web_server_ip, server_port); + if (tcp == NULL) { + net_set_state(NETLOOP_FAIL); + return; + } + wget_send(TCP_SYN, 0, 0, 0); } From patchwork Fri Aug 23 20:45:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1976256 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=qtVqmTLb; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WrBtR032Qz1yXY for ; Sat, 24 Aug 2024 06:46:07 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1BFB388C05; Fri, 23 Aug 2024 22:45:40 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b="qtVqmTLb"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D49B688BCE; Fri, 23 Aug 2024 22:45:36 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-VI1-obe.outbound.protection.outlook.com (mail-vi1eur02on20717.outbound.protection.outlook.com [IPv6:2a01:111:f403:2607::717]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 872D688B9C for ; Fri, 23 Aug 2024 22:45:34 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=k06EUtsbxPEAFGvaKWmgyKmSosI9zgqTGP5nfTXs0InZnkeYORE0RNcb2dR9XJQekxGv+/hdiMtYlCssUZFY7wdkSWGAooUccAD61YDJ1pUfo9JcO4lx0h67nhDAHzsIaQ4lvGSkOsyCUR8T4jItzfoemn3fQNJUySX1evYyvGzfPoLEUZGLyhpNYaed2Q4Cylqrcha005Ec2uCwQL0rmZkjQBn3mCMkBXioD7Ons/BqNcVBX/Mh3pVQI8RgdWnWGNZYoNF089a8yi4B1Kl+Ub1IyKdeu7AXdgDRzU4pcikhC/tBDdz2y7DfN4yr4I3QQL0qSQpK2RlGyG+2AprHhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=w9pbOhI8s5B2K1Y/7rqsd19hOSqmpKiA2CjeqvaXvxM=; b=ms2L3vSKukLNgmtUB9UJZR+wyEQ/5kkUfa3Nd2uZfglLDFfMqr7U7OtRBTsuw+3x9OIOooRt9ihUw42A9MzeRu7u5uiYq/3IPwPf19qnY5QIP6X+fmha5LPf3bDP5Rf0ySYMOEcRzGS0azZlBgivd5Te/E1ojRmzD5nQFhY28BKDHQ3WnpdZiER0QCnRKcowNuAYKYNF6n4Yy8sb+xDEJGPXN+zSXqIKS1ngEE4y/PW/nS6vK9h3kVkZlECVDSAT1UaQ3UT8zOV690++KF7ueWiiaq+0lKRK5Wwc6y+evXuVxYEqta1xxry0UmnwfxSBfuf0m6tolPCEoE/j+yihNA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu; dkim=pass header.d=iopsys.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=w9pbOhI8s5B2K1Y/7rqsd19hOSqmpKiA2CjeqvaXvxM=; b=qtVqmTLbXX40gTyJIMMfcsl2CHuhL5l0PWYu9ZWf01bVhN70rSb0VwXhd5jF9Vd6Tkdj2RsZgN23NAZQwt2G10hJMczngcTsBfgGMYJxzuIM5ja4CgLSQcaomHhtU1+SXhtXwGu1hfbjXhFJp4RvgWQ2VnfiB6SjIpg4senViZWQ167sOHAfdEtoUGtijN35UiVZ6SMtwCwBMsWSRAxqxeGrjc84cTNwM2zBq8I2qJ5wvzwGJ6Stu2LcLInuTHrjIv4aUO8u7BqWY1UfNYZtwkVL/rvFE9O91YYoWR8t6kjDu2piOWtKyw8UU/DO/9vlq1H1GT3SKcmpmP8vdRItZw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=iopsys.eu; Received: from GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) by VI0PR08MB11224.eurprd08.prod.outlook.com (2603:10a6:800:251::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.12; Fri, 23 Aug 2024 20:45:33 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7897.010; Fri, 23 Aug 2024 20:45:33 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Yasuharu Shibata , u-boot@lists.denx.de Subject: [PATCH v4 5/9] net/tcp: rename ack_edge and seq_init to more common rcv_nxt and irs Date: Fri, 23 Aug 2024 23:45:14 +0300 Message-ID: <20240823204518.1010194-6-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> References: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR4P281CA0373.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f8::20) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB11224:EE_ X-MS-Office365-Filtering-Correlation-Id: 43504b5b-1f43-48e4-a396-08dcc3b48892 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|7416014|52116014|376014|1800799024|38350700014|921020; X-Microsoft-Antispam-Message-Info: 0sGK1hhOy0x3d8ZDNlax6RijusK/o47XnBImoRoJ3ghhMqCUqy2gvh8zqL0fKSPIYIqfkr7l0OHhKS3oVtKU1J9uAc7kSwT6T8BQ5cr6NEeHzYBqcI1mjvvIAO8gSuhBl9fA39jp7r4xpDd61y2JDUn3SImDUrwuv1H1vZFTD063Ps4Wng/EdipIzYVY6h3dSWPX9lxW0cjq5B4EOdwwNlG91mluaIkDgtlxc6I+84borrWgIZmL6EK3WCVDuk2o8A8WyxJmvEYgPKm2pW5bvQtq3KCF9+BzZM0Q95zuf/vPqmrU6JJQajV/6bqXqM2ADAGxukt60TXDOXOSqds29tB6zHmGP2gkEDukatxz3Tcb1jfIbz5xTX2xJUCigUMi09uI7ZqWZjJWFDkpWRcKXazOdwClVo2t1pGjfSwfxKpbwbFCviNjnlLSlRUBJfFeg/Z+p86xxpzlk6Q5ryD+/HHxPSpWEq2IrvALW88tiqFsniJPQLHRHQrf3KkLx8dRMbTlnRsu8dtJgekJ2Vt05yaCaawMfWcxLX99uAeNHQ3aVkxijfH3g8mWcgmZduEUKVsKjVeOA3nFWOc+SSu9kTOfHGV2xDtkMq0EcQhDH1vzi0E6ltytMXQlMfqvP+h5LUp/zk9NfAWbeQP4rMCKFmCMA0C6njhlSmhphdtxpmZj458mCLbMzUeH/fzgC/Xk0SiTZS4ZJ0KOYTqwwHhhmB+zgqT/1jS5ANeX0n3TSbVMBYRWHMnoce3+aoGaxCY9gi1LoTpSrtC8mBTxpnVAgM2qVDIPSaqV2wdS66IDyNrTIZ5LKysjMI8oRFSmKYfdZty87XfM1HjYMIwaD7rXPRWrfCQT7bLaQ/xnQen1rPPX47EJWjvL0l8SOSirbcBQIThnmNSmtqR2u245l/rowcSnkmewkBiIAuXGRHoNcvGqZI5kT/5vy8QgePr0Sv68UjPOnV2ShMmSTvl8PMzkcqJLHQDnrnXdph9tz9UpBiCrs7GTwP7yngpFTDVYkb13OmAnIaf3BHYWhCBQQvtiSqNOT8grgCuxZUkGNcXY5+fyLKru9uGPTy+DNc7TEys9FMDiy4lWMJt94Kv7EG2ZCViy2JldK6gZjs7/RpV75fejtRGuekK2JTHT+/HxeLPpoS+UuiAxLB2V5V3TnaSBSdG12XHJJa+bih/5AlovSEP0aqwgONj6fuRO1htOWu9lNo669CIpB5IPAguizZNjwHoAnR0wYk+spceVpet6n0+EVCO/tmrv7J4PNHXCMSAkX6KK4C+aXiImfswpOgAFEcfPy22NtkKMJvU2nokzDcvG9lI0MkW8qe807vK2C/AiCRRMh31IkxzJzjGtrlVy2/UN0U9+iI3kNOThLe6FH5BKsrwyS4BW0hsgvUUGtnRMRMCEnLrItxxtIx1/g4GLCOE6FYJ8KFQs6mMtSzmyFBU= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(7416014)(52116014)(376014)(1800799024)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: SCIT751hQ4QirZM7rq4yhgsqUI5GiJrp97qnlgRn9gb7VDZIEh2cCUsvsUneiQ8ISaD34netdm8N2eb1pzQoX69ZVYl4xF1OeOxIue8J3yg8iMrfsEHdvuVIvrbBE0Q0OL6WbWQK29npRgJxjJKANRTc9sCQLuiz6IXEFdj9Sf/6N+XTwmbVWZa2FtQS8C15srTk3+tsN1eUT9WUm6uRkEeF9siVJpFPqUJy3l+j31QxuJI4b+vh74e1/PioyK+YbVYzfbMyOWvbt7/dzuhApCSD++MTlD8oDYS7z9FXJ039lFqsuinXdwlfEpBr6iaUKJvKooeocfgIBWxnKOegmxaIaxNVrB/BlGEttWlzavOLNHYgEcBKLGkDzU5NH9X40MRBTOM08fmwV2vkhRumuqUQ7r2/8/6/g+bqumQe7YQ+PeJdNroKuhtwM1v8Q3KDOwdbwwkihKn4IEyGmiUKRg+RlC5JW/tMXxHkZUd5VSllH9VvPMSrcDFcPQl8lrzcOIufPxVNLD6W21vmWhD76h1qKaYhQbKQoXpiqdNC6vjMMSmsbVMRtMx0TVUw0JzvFluHs6Ic2SDHsDiDU+0wLe9bgjTSGGitMAAXi4gG3iffQFEPoeZ0i2gsP0cL/eMgPb/wI84KmrhwNLBDG7Z8MPT3xKCiTJ+LNFAGv037DbjnSMZiHteiK2lYdSjmbYpBa0KFrPfvUurHji9ylPoJaxwBhweC8SHc7EeDZBRQ6zFueEEkmxIcLhLpCM+uOpRx2CNs4AupNd5315vJynLC9xHW193HDVcNdOEmwdg/sZpFjBzO/TrxC1EyCiNAl3AdYQNj6rencWWdtd6sDGy43ZolABw/cwe9gUNDh95Q1eJkvi+a0CEEcgjA2EAm+FBArYO0RivPXJptSJMi73XZtzv0CW84Dl9B3A7X/KsgsM6RRsOcqOlm+2WxWj8wdxq+MIEuafxpMW8x6vHpHMXDhSjJmDmvBOvThIFFkpjltG35N295jPmzi3xOxZifsRlCIquiCMN6LUkcNiJuim860waFhHT6VXJpLa6C2RkfUawR3+6KCXjhvjaLMXuWWoxyhKaOoM20Sb8X6VvpxbXBzTsNafW6vJehLhVRgW0+acZwunTWPPPjfbp1o22Zxk+cALSm4h2d8spSNtuugxbWy/FT6NJruwfO6501+gb7ebSDen3xgN2hKYpNRuCadCME1qTKgCq0vj5LlDjMlcA0R+BNldLi1T0xg5MDdPQJLMety3Esbko68nvVlHMflCutdicaRAF6ad/4IfKyIca6EXfYFre0qtS/N3Ma+mz1Ah8KrOs9DU2osZapuzqqIWjpokip/RSbR6rbr3JTt5ThbkMhEPpM9kAQVZLgD723XvGNQRpU4S1OMuR1Y2mCivDSiV0d6IYvpS9TMun7MlCDfJl9yJeANDIET0nqN5aMO917ExnyaxkG6M5kOWvKEHvtejoRcvNNeC4PlgPTsEcqQVagulgjZDiiu+vFZCm5SFlAJIlk5dAv9WNR0Rn2STGoxCfZ6kzAqrklnUPeIz+8Pa1dymfgQZUxchzeWXlsVTXBc/DmGYy4hYjF816NfseXeVAwoYI/fsVLdEXhgo1b2N5CaYeNA3zlLJk1ZH2vUUQ= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 43504b5b-1f43-48e4-a396-08dcc3b48892 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Aug 2024 20:45:33.3931 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8d891be1-7bce-4216-9a99-bee9de02ba58 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: lqH9S59WOgDtzJZhyAEXmd/ldlhH6PVVC+dLBUi6MYRH2WHT9jDAfZU7Lu2LxQG5mLc1kAXPIcmbVGuoBpPUbITn2gMA7DuLWe+20IKi1+Q= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB11224 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Use the names from RFC 9293 Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- include/net/tcp.h | 8 ++++---- net/tcp.c | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index f224d0cae2f..0694af9d5b1 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -285,8 +285,8 @@ enum tcp_state { * * @state: TCP connection state * - * @seq_init: Initial receive sequence number - * @ack_edge: Receive next + * @irs: Initial receive sequence number + * @rcv_nxt: Receive next * * @loc_timestamp: Local timestamp * @rmt_timestamp: Remote timestamp @@ -301,8 +301,8 @@ struct tcp_stream { /* TCP connection state */ enum tcp_state state; - u32 seq_init; - u32 ack_edge; + u32 irs; + u32 rcv_nxt; /* TCP option timestamp */ u32 loc_timestamp; diff --git a/net/tcp.c b/net/tcp.c index 9acf9f3ccb2..96d499a42ed 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -360,9 +360,9 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, pkt_len = pkt_hdr_len + payload_len; tcp_len = pkt_len - IP_HDR_SIZE; - tcp->ack_edge = tcp_ack_num; + tcp->rcv_nxt = tcp_ack_num; /* TCP Header */ - b->ip.hdr.tcp_ack = htonl(tcp->ack_edge); + b->ip.hdr.tcp_ack = htonl(tcp->rcv_nxt); b->ip.hdr.tcp_src = htons(tcp->lport); b->ip.hdr.tcp_dst = htons(tcp->rport); b->ip.hdr.tcp_seq = htonl(tcp_seq_num); @@ -396,10 +396,10 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, return pkt_hdr_len; } -static void tcp_update_ack_edge(struct tcp_stream *tcp) +static void tcp_update_rcv_nxt(struct tcp_stream *tcp) { - if (tcp_seq_cmp(tcp->ack_edge, tcp->lost.hill[0].l) >= 0) { - tcp->ack_edge = tcp->lost.hill[0].r; + if (tcp_seq_cmp(tcp->rcv_nxt, tcp->lost.hill[0].l) >= 0) { + tcp->rcv_nxt = tcp->lost.hill[0].r; memmove(&tcp->lost.hill[0], &tcp->lost.hill[1], (TCP_SACK_HILLS - 1) * sizeof(struct sack_edges)); @@ -434,7 +434,7 @@ void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) tcp_seq_num = tcp->lost.hill[i].l; } if (tcp_seq_cmp(tcp->lost.hill[i].r, tcp_seq_num + len) >= 0) { - tcp_update_ack_edge(tcp); + tcp_update_rcv_nxt(tcp); return; } @@ -463,12 +463,12 @@ void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) } } - tcp_update_ack_edge(tcp); + tcp_update_rcv_nxt(tcp); return; } if (i == TCP_SACK_HILLS) { - tcp_update_ack_edge(tcp); + tcp_update_rcv_nxt(tcp); return; } @@ -489,7 +489,7 @@ void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) tcp->lost.hill[i].r = tcp_seq_num + len; tcp->lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; - tcp_update_ack_edge(tcp); + tcp_update_rcv_nxt(tcp); }; /** @@ -566,8 +566,8 @@ static u8 tcp_state_machine(struct tcp_stream *tcp, u8 tcp_flags, debug_cond(DEBUG_INT_STATE, "TCP CLOSED %x\n", tcp_flags); if (tcp_syn) { action = TCP_SYN | TCP_ACK; - tcp->seq_init = tcp_seq_num; - tcp->ack_edge = tcp_seq_num + 1; + tcp->irs = tcp_seq_num; + tcp->rcv_nxt = tcp_seq_num + 1; tcp->lost.len = TCP_OPT_LEN_2; tcp->state = TCP_SYN_RECEIVED; } else if (tcp_ack || tcp_fin) { @@ -583,8 +583,8 @@ static u8 tcp_state_machine(struct tcp_stream *tcp, u8 tcp_flags, tcp->state = TCP_CLOSE_WAIT; } else if (tcp_ack || (tcp_syn && tcp_ack)) { action |= TCP_ACK; - tcp->seq_init = tcp_seq_num; - tcp->ack_edge = tcp_seq_num + 1; + tcp->irs = tcp_seq_num; + tcp->rcv_nxt = tcp_seq_num + 1; tcp->state = TCP_ESTABLISHED; if (tcp_syn && tcp_ack) @@ -633,7 +633,7 @@ static u8 tcp_state_machine(struct tcp_stream *tcp, u8 tcp_flags, case TCP_FIN_WAIT_1: debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_1 (%x)\n", tcp_flags); if (tcp_fin) { - tcp->ack_edge++; + tcp->rcv_nxt++; action = TCP_ACK | TCP_FIN; tcp->state = TCP_FIN_WAIT_2; } @@ -748,7 +748,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) } else if (tcp_action != TCP_DATA) { debug_cond(DEBUG_DEV_PKT, "TCP Action (action=%x,Seq=%u,Ack=%u,Pay=%d)\n", - tcp_action, tcp_ack_num, tcp->ack_edge, payload_len); + tcp_action, tcp_ack_num, tcp->rcv_nxt, payload_len); /* * Warning: Incoming Ack & Seq sequence numbers are transposed @@ -756,7 +756,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) */ net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, (tcp_action & (~TCP_PUSH)), - tcp_ack_num, tcp->ack_edge); + tcp_ack_num, tcp->rcv_nxt); } } From patchwork Fri Aug 23 20:45:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1976261 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=E2SEfwUb; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WrBvQ1bzxz1yXY for ; Sat, 24 Aug 2024 06:46:58 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id F0A0488BE4; Fri, 23 Aug 2024 22:45:44 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b="E2SEfwUb"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 26A908895A; Fri, 23 Aug 2024 22:45:40 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-VI1-obe.outbound.protection.outlook.com (mail-vi1eur02on2072f.outbound.protection.outlook.com [IPv6:2a01:111:f403:2607::72f]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id ED98788B9C for ; Fri, 23 Aug 2024 22:45:36 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=hfYrdQ9YR1XTz+KeG33QbAIUnePj71GZXIk+BadkN4sbXnW8R0huhsjgqLkejU1VQXE7nc8YB44wv/StNfnJ0KTOBBSKOvP2mXSK9vjdvgfSDe5Qax37MnYt9bP+TZtbMH7QwycwHDSreWqx2EI2BchNq+xgo6JZhnJt/vMWsl+YsEHCnPVxdB48zJP3joxI63DWghWBLnzJgNCxX5WMUoLCZ+xMIhScM4HkDI1g0rh7oM5pLrc2NwX5F5R6suz+7nVqtpLbWfQeglTsvviV8klQqbEK3ssYcCoa42rL9QsbhJJoEIwxQyhrw9rn9Od2qRgfUmoAX6//Y5lCkvhZZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=rp6LnKAD+uv5MK6B0xuEr3ZFlIel1oGEY/yjTDhEXOk=; b=vX/4HLXl2mGoy/VFn3Z9/HF1jIbp4HU2qqNTMorYaqL5nfFrgqrDpEDFCH3bUEpg8lBHy5PEOEddXfXlwRWQ7iGCjoi6vxBc10sv80mzX85Xk9f5RVbwrUhzDBo5qdOZ7W3TeIwwR1p/HdjOQSmSZXuybz0MSwkm/cMsK5Jh10pbYRWGtn0GGkeIPd33EapKJMOJ0Rbe0lnaL7+cYrdOO6oTiffTU5dXTsJPMOC2AqcPwqCoa/68cBIE26OsNMfJXDPz6c9+RbdWSe7busEHZJHBoSTSOOCxzA0BQri+A5TyxiYH2lreTn4oV3vq4YcJdB8dlgZ7XMDCUnLgp/PwBg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu; dkim=pass header.d=iopsys.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rp6LnKAD+uv5MK6B0xuEr3ZFlIel1oGEY/yjTDhEXOk=; b=E2SEfwUbTPjlGFLN4eRc/uJ8o1sPxWtJ2h4CooU2Bugb+M8iseRmTSTsaxfi+fVsymq2OkQa+M2Zo3pL2KM4QFsztj9KSIXdhnDcHOiBT1h0MbwaRK5n5frzuvxSheRyAt9TSOHuaOv0Srfvm+Ns59l3QNGg763BjpxsCTbd6ZgHPmPqUCGO2QBXbN8+0g3scTSUC5FwKXKgHqWsx/clH4gPKCiG/R243m2n+uqnjIklvXMi7IaCxS6KHFXQDFa98z0eXdurKqcruSy5D6ustITeRDZaA6Yul1FJdEd4DthmleOjQZy7SjlINB1ZymNquVnCHevy/1uuwuOutntcPQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=iopsys.eu; Received: from GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) by VI0PR08MB11224.eurprd08.prod.outlook.com (2603:10a6:800:251::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.12; Fri, 23 Aug 2024 20:45:35 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7897.010; Fri, 23 Aug 2024 20:45:34 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Yasuharu Shibata , u-boot@lists.denx.de Subject: [PATCH v4 6/9] net/tcp: improve tcp framework, use better state machine Date: Fri, 23 Aug 2024 23:45:15 +0300 Message-ID: <20240823204518.1010194-7-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> References: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR4P281CA0373.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f8::20) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB11224:EE_ X-MS-Office365-Filtering-Correlation-Id: 6b404ea6-1248-4619-355e-08dcc3b48952 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|7416014|52116014|376014|1800799024|38350700014|921020; X-Microsoft-Antispam-Message-Info: dYs1QlIlNbkIpIBoVMjBnOMU5tFrms63UtPikJXdhEPn1oPwPC1vKFViW9R4lFzizi3s6DXhVo287MwdxkIdgbQFmvYFkk1PQIUxRpB0MSqpep1M0nymkaJSwsLPHzd6+riLgRhjRa4hVaNwJIRT5duqZLW3ijOCECRhSDrepz2daHWYIsZ8eNDEVl6pIwbqgUY1U2YmsxArzO5pjd9wTKv/O8Q2Y9yg7j4TsfLs7z8kwng7j6i64lU3VbfmJvU7WQOWqgqsA8VQFRIM5G8bvkoGgN/R3KRoTz3/wg5LJx4WxjsAmqYWq0tH4l3HhN406+IGk3sjoqe/UD4vIS/ZbwUtrpWwk0knIr92+tShzmQB7Kdp3Z68sm15RLIZUz1r2nzDlN54m/IkSU57ok7E1exvJPug4XJjd47v6TlvlLzOQOU5n6T49/ZxSTBxCmTG1fPlRYOZYoDTc/Fa+W7FPlURjw6IEbQTwoJT5mFI3bPEnPsi8hcfPzIC+n8Dw3eAMn/jImGBRAzSNHgUTdsakVVUzgdkGs37Kazui2KBv9zsa7i11OGoD5Dep75svKazFNxdggGBp4jx/WxXNk3/ar07Ki8geC+CAG7hRjmmublxAnFde5n62xErfHFfm4kZTvsmfwuphCNiIu2Jlj7MCdXYFsy2NtRxByjzRhTOhVe+xuo2ff5DPxhXKm7xqKSDht/YYJNniGUwhQc3uoas4KwiGBWolrwwwbFKt/3NRniBuNkilzU3c92AU1ginT1g+yJH8jPGm7h5T6pgh1Q712w9Q/qxsDUyH+Ht8KzxKgeBLntyyLbnox0dNGlaAv0teuVPK8tOI6cpISdz/2pLzUrC3gTnflxQjRcVCxw4KbZDYqV3TIzsmGnDTDGHxc7hYL73k3+gU3nEZfEHoavBN++YtqVSPEFc6F3RO66Cw3PWTrc/SBYiXrQitCFQArZ2v0VGQtKQ47X8WNpEby7VLxCe1HVWWzD2pDEfNjVybbuNkjYR612FIooSQc4L0yhISRs9z3WYgAyyoD3gf2qnCtk1UctyOGZaVoOZ0PN7eXo9btFW4sUb/68vRUcFrWwbNK7lZJ6/WPPtRaAFnz5PXn03mlUfzU1l22HkAWaiE8hprpnYfmYvgmjMm7QYJiCopWzPVE8vHhdW74tofFhGPqx2z+Gmy3ZmD+f2ovv/a0ZH3+cNJNMSzDmGzCpjUM+5coADLW5UWA+ySk0hdAH/oLo7Z+os10g3O88dNH2fv8jA+zwioSOmPs9NBW+u1dt7HK0FX5b+C9jB+hcIkI3NZ+101BHPq27fT1W0OGHrEMZftP0kydTsrZ2QLkcKei6FCiZpz9Ey6owHbigs/SKD/s6dIvqxQr4V9m72wsuhd7KxziUPXgRtFidwYDCs7OFp/rIcmAQ/FAtDFhAm8icxquzfKUB7ko0Bb2GOZlNpCiw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(7416014)(52116014)(376014)(1800799024)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: WU0ywIb648NAneXcdwNcIoeTogvVc5sNiueDVU5tqTY0Pv5O5zQ9vP6TQlWaZb2IgcuxAT2Guhs9Vw46s5YiuvW9VqoCB7G+BwORRXJDyyBFzJ0cAuHFjxLC54UsMu+DPEQgVsgb5fzSOUBFLtM0b9VdUlZVpj15dLFktDtqqj9gKkMwF+ty2hTW38PCA8z+syYI6vi1gRERM1YR5EcyMf8lwFDTD8wAKGLwNwS2UjT46jldZD0lPumFozxvmJBbweVeJcj2TlLDXqwCglL2EA22CS5PNHu4Gc8IQtGuVzhYuSXEOCycaJImXyhVtqDjCXYVyj01dq0M4ABcXCazGeSKYNsZPk3TjPo113070dXCibB8o0hi3syu+6d8opoVkRy40XRPAXzdjJJIOXcP5GLZ0qmTOuvkdsWetEQuzu1p47qFCz3uv67DvDAan8tFoKTn8QOSezfuuOtKj/Zx41OVUb/JoWxXTVA2bm7PXCZmjxfCgnCa0bw8NW5DFuLaJkRq+vM1wVPEdgDBKoH5+Z3fvqKQg2MijHjlMhn4+GGBV+6+MgY6k/X1G41yjCz4XM3hvwjB9wKsQ4D/7vsmV3U2treB4kY1tyofgtQfm5tNCqN8SWocWcAjZIhhqbezEglmjn4VUBceQSJ8k7VY98mRPPOmaRDfvikYjaDCUHAA6j3FVSmQp6azj3KeUjGjhN9hlSpxb4SNfGXdEN0AEQeCTlKbJaO0LNy72PP3kV1ff5Z0PIZp66o0xsUSNNC7eHYV6UGogRjlKjYK91+hR3CenG6jTLcLP9fSXdksEVhEcuKtJjkXJdieUmDVYM4NV3pP2IEtfflIboWLERizHJlukiXFJa6SY0qaxa3yhqwjW84p27wds3yyA6nztDEvw9XH9LSvCwPp5H7pCYaiKzetlJm7bkNwMy0exhAWFP1t/bfttwY41uEmUPyHDWxywtJRGw3aq3Q7RkllNGNMsD3azVhmqeCMxeYVmcwK2/Be/LQAdE6qiTzgNuGONdGWczIi+K+UmE5lKNenEVdfpoH/Vvx6gII/7V4XD62JwFhGqbnMpnsAxfubWlz4KalNa6gAS+fein9h+iuhiolnQFyV6QTyQ8pCIf8XR1XDsUbqz+6oVbWZBzTGI+iZgXJ8skx8EG0QwJH53hoen1vG/zj94wDKKmBmubQEM9ZK+gei9gUUJgAsKL8oXOqblxTvGWWcDdZXUKXWR5XVsqcEj1UlhgHHc8i9NiASQNulOFtCvU/YFcCxR/E53aU0mMUW3BjJBT2VxR+dbFAy+P6T+vXBhYttRD+N5SndrT5REDWXwXrDyg2sQJ+gqo64i16WjbURGZhdG5xk66yYOaZAwfMgGM1imAVe38ANTxsRoTfLnG4HVrsN3BOiyKuUYeRJ0RGDa2Kkk/JwrfjDA7bxBo978LRRvbXK5p4CkRw/BDjvOdM+EzUDyU+u1XbMYuiPOVyrKWMB0Fgbzdo4FQE5C2xDuJ+6oi8fNv4FvTOqtx8HkefuksXj0Z9yHYyns3cA/MvqTXDwZLjd2Y19bNzzTHW1HSnHw6m0o8pUQgE2L1+igaqu44YIawgwYoG09YSFqZw7nceGjIdWb7mxjBqboFSlIhaxOL9I2/IrtbR8vMw= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 6b404ea6-1248-4619-355e-08dcc3b48952 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Aug 2024 20:45:34.7105 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8d891be1-7bce-4216-9a99-bee9de02ba58 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: CvkGnhV/EhxF0SOiMQRJGQxvVthHbaiDRj3of5YeMTKR+io6qTaZBtcfhOeilySi2WF8A8oZQ3qyfO+xP91qbxSpbG7nJkCIcdJjQtwWyH4= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB11224 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Changes: * Fix initial send sequence always zero issue * Use state machine close to RFC 9293. This should make TCP transfers more reliable (now we can upload a huge array of data from the board to external server) * Improve TCP framework a lot. This should make tcp client code much more simple. * rewrite wget with new tcp stack * rewrite fastboot_tcp with new tcp stack Signed-off-by: Mikhail Kshevetskiy --- include/net/tcp.h | 171 +++++++-- include/net/wget.h | 8 - net/fastboot_tcp.c | 190 +++++----- net/net.c | 4 + net/tcp.c | 837 ++++++++++++++++++++++++++++++++++----------- net/wget.c | 460 +++++++------------------ 6 files changed, 992 insertions(+), 678 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 0694af9d5b1..b070354e871 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -265,6 +265,7 @@ union tcp_build_pkt { * @TCP_CLOSING: Rec FIN, sent FIN, ACK waiting for ACK * @TCP_FIN_WAIT_1: Sent FIN waiting for response * @TCP_FIN_WAIT_2: Rec ACK from FIN sent, waiting for FIN + * @TCP_LAST_ACK: Waiting for ACK of the connection termination */ enum tcp_state { TCP_CLOSED, @@ -274,7 +275,20 @@ enum tcp_state { TCP_CLOSE_WAIT, TCP_CLOSING, TCP_FIN_WAIT_1, - TCP_FIN_WAIT_2 + TCP_FIN_WAIT_2, + TCP_LAST_ACK, +}; + +/** + * enum tcp_status - TCP stream status for connection + * @TCP_ERR_OK: no rx/tx errors + * @TCP_ERR_TOUT: rx/tx timeout happened + * @TCP_ERR_RST: connection was reset + */ +enum tcp_status { + TCP_ERR_OK = 0, + TCP_ERR_TOUT, + TCP_ERR_RST, }; /** @@ -283,51 +297,150 @@ enum tcp_state { * @rport: Remote port, host byte order * @lport: Local port, host byte order * + * @priv: User private data (not used by tcp module) + * + * @max_retry_count: Maximum retransmit attempts (default 3) + * @initial_timeout: Timeout from initial TX to reTX (default 2 sec) + * @rx_inactiv_timeout: Maximum time from last rx till connection drop + * (default 30 sec) + * + * @on_closed: User callback, called just before destroying TCP stream + * @on_established: User callback, called when TCP stream enters + * TCP_ESTABLISHED state + * @on_rcv_nxt_update: User callback, called when all data in the segment + * [0..rx_bytes - 1] was received + * @on_snd_una_update: User callback, called when all data in the segment + * [0..tx_bytes - 1] were transferred and acknowledged + * @rx: User callback, called on receive of segment + * [rx_offs..rx_offs+len-1]. If NULL -- all incoming data + * will be ignored. User SHOULD store the segment and + * return the number of accepted bytes. + * WARNING: Previous segmengs may not be received yet + * @tx: User callback, called on transmit/retransmit of segment + * [tx_offs..tx_offs+maxlen-1]. If NULL -- no data will + * be transmitted. User SHOULD fill provided buffer and + * return the number of bytes in the buffer. + * WARNING: do not use tcp_stream_close() from this + * callback (it will break stream). Better use + * on_snd_una_update() callback for such purposes. + * + * @time_last_rx: Arrival time of last valid incoming package (ticks) + * @time_start: Timeout start time (ticks) + * @time_delta: Timeout duration (ticks) + * @time_handler Timeout handler for a stream + * * @state: TCP connection state + * @status: TCP stream status (OK or ERR) + * + * @fin_rx: Non-zero if TCP_FIN was received + * @fin_rx_seq: TCP sequence of rx FIN bit + * @fin_tx: Non-zero if TCP_FIN was sent (or planned to send) + * @fin_tx_seq: TCP sequence of tx FIN bit + * + * @iss: Initial send sequence number + * @snd_una: Send unacknowledged + * @snd_nxt: Send next + * @snd_wnd: Send window (in bytes) + * @snd_wl1: Segment sequence number used for last window update + * @snd_wl2: Segment acknowledgment number used for last window update * * @irs: Initial receive sequence number * @rcv_nxt: Receive next + * @rcv_wnd: Receive window (in bytes) * * @loc_timestamp: Local timestamp * @rmt_timestamp: Remote timestamp * + * @rmt_win_scale: Remote window scale factor + * * @lost: Used for SACK + * + * @retry_cnt: Number of retry attempts remaining. Only SYN, FIN + * or DATA segments are tried to retransmit. + * @retry_timeout: Current retry timeout (ms) + * @retry_action: TCP flags used for sending + * @retry_seq_num: TCP sequence for retransmit + * retry_tx_len: Number of data to transmit + * @retry_tx_offs: Position in the TX stream */ struct tcp_stream { struct in_addr rhost; u16 rport; u16 lport; - /* TCP connection state */ + void *priv; + + int max_retry_count; + int initial_timeout; + int rx_inactiv_timeout; + + void (*on_closed)(struct tcp_stream *tcp); + void (*on_established)(struct tcp_stream *tcp); + void (*on_rcv_nxt_update)(struct tcp_stream *tcp, u32 rx_bytes); + void (*on_snd_una_update)(struct tcp_stream *tcp, u32 tx_bytes); + u32 (*rx)(struct tcp_stream *tcp, u32 rx_offs, void *buf, u32 len); + u32 (*tx)(struct tcp_stream *tcp, u32 tx_offs, void *buf, u32 maxlen); + + ulong time_last_rx; + ulong time_start; + ulong time_delta; + void (*time_handler)(struct tcp_stream *tcp); + enum tcp_state state; + enum tcp_status status; + + int fin_rx; + u32 fin_rx_seq; + + int fin_tx; + u32 fin_tx_seq; + + u32 iss; + u32 snd_una; + u32 snd_nxt; + u32 snd_wnd; + u32 snd_wl1; + u32 snd_wl2; u32 irs; u32 rcv_nxt; + u32 rcv_wnd; /* TCP option timestamp */ u32 loc_timestamp; u32 rmt_timestamp; + /* TCP window scale */ + u8 rmt_win_scale; + /* TCP sliding window control used to request re-TX */ struct tcp_sack_v lost; + + /* used for data retransmission */ + int retry_cnt; + int retry_timeout; + u8 retry_action; + u32 retry_seq_num; + u32 retry_tx_len; + u32 retry_tx_offs; }; void tcp_init(void); -typedef int tcp_incoming_filter(struct in_addr rhost, - u16 rport, u16 sport); - /* - * This function sets user callback used to accept/drop incoming - * connections. Callback should: + * This function sets user callback called on TCP stream creation. + * Callback should: * + Check TCP stream endpoint and make connection verdict * - return non-zero value to accept connection * - return zero to drop connection + * + Setup TCP stream callbacks like: on_closed(), on_established(), + * n_rcv_nxt_update(), on_snd_una_update(), rx() and tx(). + * + Setup other stream related data * - * WARNING: If callback is NOT defined, all incoming connections - * will be dropped. + * WARNING: User MUST setup TCP stream on_create handler. Without it + * no connection (including outgoung) will be created. */ -void tcp_set_incoming_filter(tcp_incoming_filter *filter); +void tcp_stream_set_on_create_handler(int (*on_create)(struct tcp_stream *)); /* * tcp_stream_get -- Get or create TCP stream @@ -351,28 +464,30 @@ struct tcp_stream *tcp_stream_get(int is_new, struct in_addr rhost, */ struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport); -enum tcp_state tcp_stream_get_state(struct tcp_stream *tcp); +/* + * tcp_stream_put -- Return stream to a TCP subsystem. Subsystem will + * check stream and destroy it (if stream was already + * closed). Otherwize no stream change will happen. + * @tcp: TCP stream to put + */ +void tcp_stream_put(struct tcp_stream *tcp); + +enum tcp_state tcp_stream_get_state(struct tcp_stream *tcp); +enum tcp_status tcp_stream_get_status(struct tcp_stream *tcp); + +u32 tcp_stream_rx_offs(struct tcp_stream *tcp); +u32 tcp_stream_tx_offs(struct tcp_stream *tcp); + +/* reset tcp stream */ +void tcp_stream_reset(struct tcp_stream *tcp); +/* force TCP stream closing, do NOT use from tcp->tx callback */ +void tcp_stream_close(struct tcp_stream *tcp); + +void tcp_streams_poll(void); int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num); -/** - * rxhand_tcp() - An incoming packet handler. - * @tcp: TCP stream - * @pkt: pointer to the application packet - * @dport: destination TCP port - * @sip: source IP address - * @sport: source TCP port - * @tcp_seq_num: TCP sequential number - * @tcp_ack_num: TCP acknowledgment number - * @action: TCP action (SYN, ACK, FIN, etc) - * @len: packet length - */ -typedef void rxhand_tcp(struct tcp_stream *tcp, uchar *pkt, - u32 tcp_seq_num, u32 tcp_ack_num, - u8 action, unsigned int len); -void tcp_set_tcp_handler(rxhand_tcp *f); - void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int len); u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, struct in_addr dest, diff --git a/include/net/wget.h b/include/net/wget.h index 6714f7ea573..9a423b30414 100644 --- a/include/net/wget.h +++ b/include/net/wget.h @@ -8,14 +8,6 @@ */ void wget_start(void); -enum wget_state { - WGET_CLOSED, - WGET_CONNECTING, - WGET_CONNECTED, - WGET_TRANSFERRING, - WGET_TRANSFERRED -}; - #define DEBUG_WGET 0 /* Set to 1 for debug messages */ #define WGET_RETRY_COUNT 30 #define WGET_TIMEOUT 2000UL diff --git a/net/fastboot_tcp.c b/net/fastboot_tcp.c index 12a4d6690be..b6f7c417a21 100644 --- a/net/fastboot_tcp.c +++ b/net/fastboot_tcp.c @@ -10,140 +10,106 @@ #define FASTBOOT_TCP_PORT 5554 -static char command[FASTBOOT_COMMAND_LEN] = {0}; -static char response[FASTBOOT_RESPONSE_LEN] = {0}; - static const unsigned short handshake_length = 4; static const uchar *handshake = "FB01"; -static u32 curr_tcp_seq_num; -static u32 curr_tcp_ack_num; -static unsigned int curr_request_len; -static enum fastboot_tcp_state { - FASTBOOT_CLOSED, - FASTBOOT_CONNECTED, - FASTBOOT_DISCONNECTING -} state = FASTBOOT_CLOSED; - -static void fastboot_tcp_answer(struct tcp_stream *tcp, u8 action, - unsigned int len) -{ - const u32 response_seq_num = curr_tcp_ack_num; - const u32 response_ack_num = curr_tcp_seq_num + - (curr_request_len > 0 ? curr_request_len : 1); +static char rxbuf[sizeof(u64) + FASTBOOT_COMMAND_LEN + 1]; +static char txbuf[sizeof(u64) + FASTBOOT_RESPONSE_LEN + 1]; - net_send_tcp_packet(len, tcp->rhost, tcp->rport, tcp->lport, - action, response_seq_num, response_ack_num); -} +static u32 data_read; +static u32 tx_last_offs, tx_last_len; -static void fastboot_tcp_reset(struct tcp_stream *tcp) +static void tcp_stream_on_rcv_nxt_update(struct tcp_stream *tcp, u32 rx_bytes) { - fastboot_tcp_answer(tcp, TCP_RST, 0); - state = FASTBOOT_CLOSED; -} + u64 cmd_size; + __be64 len_be; + char saved; + int fastboot_command_id, len; + + if ((data_read == 0) && (rx_bytes >= handshake_length)) { + if (memcmp(rxbuf, handshake, handshake_length) != 0) { + printf("fastboot: bad handshake\n"); + tcp_stream_close(tcp); + return; + } -static void fastboot_tcp_send_packet(struct tcp_stream *tcp, u8 action, - const uchar *data, unsigned int len) -{ - uchar *pkt = net_get_async_tx_pkt_buf(); + tx_last_offs = 0; + tx_last_len = handshake_length; + memcpy(txbuf, handshake, handshake_length); + + data_read += handshake_length; + rx_bytes -= handshake_length; + if (rx_bytes > 0) + memmove(rxbuf, rxbuf + handshake_length, rx_bytes); + return; + } - memset(pkt, '\0', PKTSIZE); - pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; - memcpy(pkt, data, len); - fastboot_tcp_answer(tcp, action, len); - memset(pkt, '\0', PKTSIZE); + if (rx_bytes < sizeof(u64)) + return; + + memcpy(&cmd_size, rxbuf, sizeof(u64)); + cmd_size = __be64_to_cpu(cmd_size); + if (rx_bytes < sizeof(u64) + cmd_size) + return; + + saved = rxbuf[sizeof(u64) + cmd_size]; + rxbuf[sizeof(u64) + cmd_size] = '\0'; + fastboot_command_id = fastboot_handle_command(rxbuf + sizeof(u64), + txbuf + sizeof(u64)); + fastboot_handle_boot(fastboot_command_id, + strncmp("OKAY", txbuf + sizeof(u64), 4) != 0); + rxbuf[sizeof(u64) + cmd_size] = saved; + + len = strlen(txbuf + sizeof(u64)); + len_be = __cpu_to_be64(len); + memcpy(txbuf, &len_be, sizeof(u64)); + + tx_last_offs += tx_last_len; + tx_last_len = len + sizeof(u64); + + data_read += sizeof(u64) + cmd_size; + rx_bytes -= sizeof(u64) + cmd_size; + if (rx_bytes > 0) + memmove(rxbuf, rxbuf + sizeof(u64) + cmd_size, rx_bytes); } -static void fastboot_tcp_send_message(struct tcp_stream *tcp, - const char *message, unsigned int len) +static u32 tcp_stream_rx(struct tcp_stream *tcp, u32 rx_offs, void *buf, u32 len) { - __be64 len_be = __cpu_to_be64(len); - uchar *pkt = net_get_async_tx_pkt_buf(); - - memset(pkt, '\0', PKTSIZE); - pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; - // Put first 8 bytes as a big endian message length - memcpy(pkt, &len_be, 8); - pkt += 8; - memcpy(pkt, message, len); - fastboot_tcp_answer(tcp, TCP_ACK | TCP_PUSH, len + 8); - memset(pkt, '\0', PKTSIZE); + memcpy(rxbuf + rx_offs - data_read, buf, len); + return len; } -static void fastboot_tcp_handler_ipv4(struct tcp_stream *tcp, uchar *pkt, - u32 tcp_seq_num, u32 tcp_ack_num, - u8 action, unsigned int len) +static u32 tcp_stream_tx(struct tcp_stream *tcp, u32 tx_offs, void *buf, u32 maxlen) { - int fastboot_command_id; - u64 command_size; - u8 tcp_fin = action & TCP_FIN; - u8 tcp_push = action & TCP_PUSH; - - curr_tcp_seq_num = tcp_seq_num; - curr_tcp_ack_num = tcp_ack_num; - curr_request_len = len; - - switch (state) { - case FASTBOOT_CLOSED: - if (tcp_push) { - if (len != handshake_length || - strlen(pkt) != handshake_length || - memcmp(pkt, handshake, handshake_length) != 0) { - fastboot_tcp_reset(tcp); - break; - } - fastboot_tcp_send_packet(tcp, TCP_ACK | TCP_PUSH, - handshake, handshake_length); - state = FASTBOOT_CONNECTED; - } - break; - case FASTBOOT_CONNECTED: - if (tcp_fin) { - fastboot_tcp_answer(tcp, TCP_FIN | TCP_ACK, 0); - state = FASTBOOT_DISCONNECTING; - break; - } - if (tcp_push) { - // First 8 bytes is big endian message length - command_size = __be64_to_cpu(*(u64 *)pkt); - len -= 8; - pkt += 8; - - // Only single packet messages are supported ATM - if (strlen(pkt) != command_size) { - fastboot_tcp_reset(tcp); - break; - } - strlcpy(command, pkt, len + 1); - fastboot_command_id = fastboot_handle_command(command, response); - fastboot_tcp_send_message(tcp, response, strlen(response)); - fastboot_handle_boot(fastboot_command_id, - strncmp("OKAY", response, 4) == 0); - } - break; - case FASTBOOT_DISCONNECTING: - if (tcp_push) - state = FASTBOOT_CLOSED; - break; - } + /* by design: tx_offs >= tx_last_offs */ + if (tx_offs >= tx_last_offs + tx_last_len) + return 0; - memset(command, 0, FASTBOOT_COMMAND_LEN); - memset(response, 0, FASTBOOT_RESPONSE_LEN); - curr_tcp_seq_num = 0; - curr_tcp_ack_num = 0; - curr_request_len = 0; + maxlen = tx_last_offs + tx_last_len - tx_offs; + memcpy(buf, txbuf + (tx_offs - tx_last_offs), maxlen); + return maxlen; } -static int incoming_filter(struct in_addr rhost, u16 rport, u16 lport) +static int tcp_stream_on_create(struct tcp_stream *tcp) { - return (lport == FASTBOOT_TCP_PORT); + if (tcp->lport != FASTBOOT_TCP_PORT) + return 0; + + data_read = 0; + tx_last_offs = 0; + tx_last_len = 0; + + tcp->on_rcv_nxt_update = tcp_stream_on_rcv_nxt_update; + tcp->rx = tcp_stream_rx; + tcp->tx = tcp_stream_tx; + return 1; } void fastboot_tcp_start_server(void) { + memset(net_server_ethaddr, 0, 6); + tcp_stream_set_on_create_handler(tcp_stream_on_create); + printf("Using %s device\n", eth_get_name()); printf("Listening for fastboot command on tcp %pI4\n", &net_ip); - - tcp_set_incoming_filter(incoming_filter); - tcp_set_tcp_handler(fastboot_tcp_handler_ipv4); } diff --git a/net/net.c b/net/net.c index b33ea59a9fa..86182cc504e 100644 --- a/net/net.c +++ b/net/net.c @@ -646,6 +646,9 @@ restart: * errors that may have happened. */ eth_rx(); +#if defined(CONFIG_PROT_TCP) + tcp_streams_poll(); +#endif /* * Abort if ctrl-c was pressed. @@ -952,6 +955,7 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, + tcp_set_tcp_header(tcp, pkt + eth_hdr_size, payload_len, action, tcp_seq_num, tcp_ack_num); + tcp_stream_put(tcp); break; #endif default: diff --git a/net/tcp.c b/net/tcp.c index 96d499a42ed..2c34556c26d 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -24,9 +24,18 @@ #include #include -static int tcp_activity_count; +#define TCP_SEND_RETRY 3 +#define TCP_SEND_TIMEOUT 2000UL +#define TCP_RX_INACTIVE_TIMEOUT 30000UL +#define TCP_START_SEQ_INC 2153 /* just large prime number */ +#define TCP_RCV_WND_SIZE (PKTBUFSRX * TCP_MSS) + +#define TCP_PACKET_OK 0 +#define TCP_PACKET_DROP 1 + static struct tcp_stream tcp_stream; -static tcp_incoming_filter *incoming_filter; + +static int (*tcp_stream_on_create)(struct tcp_stream *tcp); /* * TCP lengths are stored as a rounded up number of 32 bit words. @@ -35,12 +44,10 @@ static tcp_incoming_filter *incoming_filter; */ #define LEN_B_TO_DW(x) ((x) >> 2) #define ROUND_TCPHDR_LEN(x) (LEN_B_TO_DW((x) + 3)) +#define ROUND_TCPHDR_BYTES(x) (((x) + 3) & ~3) #define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4) #define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2) -/* Current TCP RX packet handler */ -static rxhand_tcp *tcp_packet_handler; - #define RANDOM_PORT_START 1024 #define RANDOM_PORT_RANGE 0x4000 @@ -62,6 +69,21 @@ static inline s32 tcp_seq_cmp(u32 a, u32 b) return (s32)(a - b); } +static inline u32 tcp_get_start_seq(void) +{ + static u32 tcp_seq_inc; + u32 tcp_seq; + + tcp_seq = (get_timer(0) & 0xffffffff) + tcp_seq_inc; + tcp_seq_inc += TCP_START_SEQ_INC; + return tcp_seq; +} + +static inline ulong msec_to_ticks(ulong msec) +{ + return msec * CONFIG_SYS_HZ / 1000; +} + /** * tcp_stream_get_state() - get TCP stream state * @tcp: tcp stream @@ -84,15 +106,70 @@ static void tcp_stream_set_state(struct tcp_stream *tcp, tcp->state = new_state; } +/** + * tcp_stream_get_status() - get TCP stream status + * @tcp: tcp stream + * + * Return: TCP stream status + */ +enum tcp_status tcp_stream_get_status(struct tcp_stream *tcp) +{ + return tcp->status; +} + +/** + * tcp_stream_set_status() - set TCP stream state + * @tcp: tcp stream + * @new_satus: new TCP stream status + */ +static void tcp_stream_set_status(struct tcp_stream *tcp, + enum tcp_state new_status) +{ + tcp->status = new_status; +} + +static void tcp_stream_init(struct tcp_stream *tcp, + struct in_addr rhost, u16 rport, u16 lport) +{ + memset(tcp, 0, sizeof(struct tcp_stream)); + tcp->rhost.s_addr = rhost.s_addr; + tcp->rport = rport; + tcp->lport = lport; + tcp->state = TCP_CLOSED; + tcp->lost.len = TCP_OPT_LEN_2; + tcp->rcv_wnd = TCP_RCV_WND_SIZE; + tcp->max_retry_count = TCP_SEND_RETRY; + tcp->initial_timeout = TCP_SEND_TIMEOUT; + tcp->rx_inactiv_timeout = TCP_RX_INACTIVE_TIMEOUT; + tcp->time_last_rx = get_timer(0); +} + +static void tcp_stream_destroy(struct tcp_stream *tcp) +{ + if (tcp->on_closed != NULL) + tcp->on_closed(tcp); + memset(tcp, 0, sizeof(struct tcp_stream)); +} + void tcp_init(void) { - incoming_filter = NULL; - tcp_stream.state = TCP_CLOSED; + static int initialized; + struct tcp_stream *tcp = &tcp_stream; + + tcp_stream_on_create = NULL; + if (!initialized) { + initialized = 1; + memset(tcp, 0, sizeof(struct tcp_stream)); + } + + tcp_stream_set_state(tcp, TCP_CLOSED); + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_destroy(tcp); } -void tcp_set_incoming_filter(tcp_incoming_filter *filter) +void tcp_stream_set_on_create_handler(int (*on_create)(struct tcp_stream *)) { - incoming_filter = filter; + tcp_stream_on_create = on_create; } static struct tcp_stream *tcp_stream_add(struct in_addr rhost, @@ -100,15 +177,14 @@ static struct tcp_stream *tcp_stream_add(struct in_addr rhost, { struct tcp_stream *tcp = &tcp_stream; - if (tcp->state != TCP_CLOSED) + if ((tcp_stream_on_create == NULL) || + (tcp->state != TCP_CLOSED)) + return NULL; + + tcp_stream_init(tcp, rhost, rport, lport); + if (!tcp_stream_on_create(tcp)) return NULL; - memset(tcp, 0, sizeof(struct tcp_stream)); - tcp->rhost.s_addr = rhost.s_addr; - tcp->rport = rport; - tcp->lport = lport; - tcp->state = TCP_CLOSED; - tcp->lost.len = TCP_OPT_LEN_2; return tcp; } @@ -122,30 +198,203 @@ struct tcp_stream *tcp_stream_get(int is_new, struct in_addr rhost, (tcp->lport == lport)) return tcp; - if (!is_new || (incoming_filter == NULL) || - !incoming_filter(rhost, rport, lport)) - return NULL; + return is_new ? tcp_stream_add(rhost, rport, lport) : NULL; +} - return tcp_stream_add(rhost, rport, lport); +void tcp_stream_put(struct tcp_stream *tcp) +{ + if (tcp->state == TCP_CLOSED) + tcp_stream_destroy(tcp); } -static void dummy_handler(struct tcp_stream *tcp, uchar *pkt, - u32 tcp_seq_num, u32 tcp_ack_num, - u8 action, unsigned int len) +u32 tcp_stream_rx_offs(struct tcp_stream *tcp) { + u32 ret; + + switch (tcp->state) { + case TCP_CLOSED: + case TCP_SYN_SENT: + case TCP_SYN_RECEIVED: + return 0; + default: + break; + } + + ret = tcp->rcv_nxt - tcp->irs - 1; + if (tcp->fin_rx && (tcp->rcv_nxt == tcp->fin_rx_seq)) + ret--; + return ret; } -/** - * tcp_set_tcp_handler() - set a handler to receive data - * @f: handler - */ -void tcp_set_tcp_handler(rxhand_tcp *f) +u32 tcp_stream_tx_offs(struct tcp_stream *tcp) { - debug_cond(DEBUG_INT_STATE, "--- net_loop TCP handler set (%p)\n", f); - if (!f) - tcp_packet_handler = dummy_handler; - else - tcp_packet_handler = f; + u32 ret; + + switch (tcp->state) { + case TCP_CLOSED: + case TCP_SYN_SENT: + case TCP_SYN_RECEIVED: + return 0; + default: + break; + } + + ret = tcp->snd_una - tcp->iss - 1; + if (tcp->fin_tx && (tcp->snd_una == tcp->fin_tx_seq + 1)) + ret--; + return ret; +} + +static void tcp_stream_set_time_handler(struct tcp_stream *tcp, ulong msec, + void (*handler)(struct tcp_stream *)) +{ + if (msec == 0) { + tcp->time_handler = NULL; + return; + } + + tcp->time_handler = handler; + tcp->time_start = get_timer(0); + tcp->time_delta = msec_to_ticks(msec); +} + +static void tcp_send_packet(struct tcp_stream *tcp, u8 action, + u32 tcp_seq_num, u32 tcp_ack_num, u32 tx_len) +{ + net_send_tcp_packet(tx_len, tcp->rhost, tcp->rport, + tcp->lport, action, tcp_seq_num, + tcp_ack_num); +} + +static void tcp_send_repeat(struct tcp_stream *tcp) +{ + uchar *ptr; + u32 tcp_opts_size; + + if (tcp->retry_cnt == 0) { + puts("\nTCP: send retry counter exceeded\n"); + tcp_send_packet(tcp, TCP_RST, tcp->retry_seq_num, + tcp->rcv_nxt, 0); + tcp_stream_set_status(tcp, TCP_ERR_TOUT); + tcp_stream_set_state(tcp, TCP_CLOSED); + tcp_stream_destroy(tcp); + return; + } + tcp->retry_cnt--; + tcp->retry_timeout += tcp->initial_timeout; + + if (tcp->retry_tx_len > 0) { + tcp_opts_size = ROUND_TCPHDR_BYTES(TCP_TSOPT_SIZE + + tcp->lost.len); + ptr = net_tx_packet + net_eth_hdr_size() + + IP_TCP_HDR_SIZE + tcp_opts_size; + + if (tcp->retry_tx_len > TCP_MSS - tcp_opts_size) + tcp->retry_tx_len = TCP_MSS - tcp_opts_size; + + /* refill packet data */ + tcp->tx(tcp, tcp->retry_tx_offs, ptr, tcp->retry_tx_len); + } + tcp_send_packet(tcp, tcp->retry_action, tcp->retry_seq_num, + tcp->rcv_nxt, tcp->retry_tx_len); + + tcp_stream_set_time_handler(tcp, tcp->retry_timeout, tcp_send_repeat); +} + +static void tcp_send_packet_with_retry(struct tcp_stream *tcp, u8 action, + u32 tcp_seq_num, u32 tx_len, u32 tx_offs) +{ + tcp->retry_cnt = tcp->max_retry_count; + tcp->retry_timeout = tcp->initial_timeout; + tcp->retry_action = action; + tcp->retry_seq_num = tcp_seq_num; + tcp->retry_tx_len = tx_len; + tcp->retry_tx_offs = tx_offs; + + tcp_send_packet(tcp, action, tcp_seq_num, tcp->rcv_nxt, tx_len); + tcp_stream_set_time_handler(tcp, tcp->retry_timeout, tcp_send_repeat); +} + +static inline u8 tcp_stream_fin_needed(struct tcp_stream *tcp, u32 tcp_seq_num) +{ + return (tcp->fin_tx && (tcp_seq_num == tcp->fin_tx_seq)) ? TCP_FIN : 0; +} + +static void tcp_steam_tx_try(struct tcp_stream *tcp) +{ + uchar *ptr; + u32 tx_offs, tx_len, tcp_opts_size; + + if ((tcp->state != TCP_ESTABLISHED) || + (tcp->time_handler != NULL) || + (tcp->tx == NULL)) + return; + + tcp_opts_size = ROUND_TCPHDR_BYTES(TCP_TSOPT_SIZE + tcp->lost.len); + tx_len = TCP_MSS - tcp_opts_size; + if (tcp->fin_tx) { + /* do not try to send beyonds FIN packet limits */ + if (tcp_seq_cmp(tcp->snd_una, tcp->fin_tx_seq) >= 0) + return; + + tx_len = tcp->fin_tx_seq - tcp->snd_una; + if (tx_len > TCP_MSS - tcp_opts_size) + tx_len = TCP_MSS - tcp_opts_size; + } + + tx_offs = tcp_stream_tx_offs(tcp); + ptr = net_tx_packet + net_eth_hdr_size() + + IP_TCP_HDR_SIZE + tcp_opts_size; + + /* fill packet data and adjust size */ + tx_len = tcp->tx(tcp, tx_offs, ptr, tx_len); + if (tx_len == 0) + return; + + if (tcp_seq_cmp(tcp->snd_una + tx_len, tcp->snd_nxt) > 0) + tcp->snd_nxt = tcp->snd_una + tx_len; + + tcp_send_packet_with_retry(tcp, TCP_ACK | TCP_PUSH, + tcp->snd_una, tx_len, tx_offs); +} + +static void tcp_stream_poll(struct tcp_stream *tcp, ulong time) +{ + ulong delta; + void (*handler)(struct tcp_stream *tcp); + + if (tcp->state == TCP_CLOSED) + return; + + /* handle rx inactivity timeout */ + delta = msec_to_ticks(tcp->rx_inactiv_timeout); + if (time - tcp->time_last_rx >= delta) { + puts("\nTCP: rx inactivity timeout exceeded\n"); + tcp_stream_reset(tcp); + tcp_stream_set_status(tcp, TCP_ERR_TOUT); + tcp_stream_destroy(tcp); + return; + } + + /* handle retransmit timeout */ + if ((tcp->time_handler != NULL) && + (time - tcp->time_start >= tcp->time_delta)) { + handler = tcp->time_handler; + tcp->time_handler = NULL; + handler(tcp); + } + + tcp_steam_tx_try(tcp); +} + +void tcp_streams_poll(void) +{ + ulong time; + struct tcp_stream *tcp; + + time = get_timer(0); + tcp = &tcp_stream; + tcp_stream_poll(tcp, time); } /** @@ -300,18 +549,8 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, "TCP Hdr:SYN (%pI4, %pI4, sq=%u, ak=%u)\n", &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); - tcp_activity_count = 0; net_set_syn_options(tcp, b); - tcp_seq_num = 0; - tcp_ack_num = 0; pkt_hdr_len = IP_TCP_O_SIZE; - if (tcp->state == TCP_SYN_SENT) { /* Too many SYNs */ - action = TCP_FIN; - tcp->state = TCP_FIN_WAIT_1; - } else { - tcp->lost.len = TCP_OPT_LEN_2; - tcp->state = TCP_SYN_SENT; - } break; case TCP_SYN | TCP_ACK: case TCP_ACK: @@ -328,21 +567,16 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); payload_len = 0; pkt_hdr_len = IP_TCP_HDR_SIZE; - tcp->state = TCP_FIN_WAIT_1; break; case TCP_RST | TCP_ACK: case TCP_RST: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:RST (%pI4, %pI4, s=%u, a=%u)\n", &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); - tcp->state = TCP_CLOSED; break; /* Notify connection closing */ case (TCP_FIN | TCP_ACK): case (TCP_FIN | TCP_ACK | TCP_PUSH): - if (tcp->state == TCP_CLOSE_WAIT) - tcp->state = TCP_CLOSING; - debug_cond(DEBUG_DEV_PKT, "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%u, a=%u, A=%x)\n", &tcp->rhost, &net_ip, @@ -382,7 +616,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, * it is, then the u-boot tftp or nfs kernel netboot should be * considered. */ - b->ip.hdr.tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE); + b->ip.hdr.tcp_win = htons(tcp->rcv_wnd >> TCP_SCALE); b->ip.hdr.tcp_xsum = 0; b->ip.hdr.tcp_ugr = 0; @@ -501,6 +735,7 @@ void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) void tcp_parse_options(struct tcp_stream *tcp, uchar *o, int o_len) { struct tcp_t_opt *tsopt; + struct tcp_scale *wsopt; uchar *p = o; /* @@ -515,10 +750,13 @@ void tcp_parse_options(struct tcp_stream *tcp, uchar *o, int o_len) case TCP_O_END: return; case TCP_O_MSS: - case TCP_O_SCL: case TCP_P_SACK: case TCP_V_SACK: break; + case TCP_O_SCL: + wsopt = (struct tcp_scale *)p; + tcp->rmt_win_scale = wsopt->scale; + break; case TCP_O_TS: tsopt = (struct tcp_t_opt *)p; tcp->rmt_timestamp = tsopt->t_snd; @@ -533,129 +771,330 @@ void tcp_parse_options(struct tcp_stream *tcp, uchar *o, int o_len) } } -static u8 tcp_state_machine(struct tcp_stream *tcp, u8 tcp_flags, - u32 tcp_seq_num, int payload_len) +static int tcp_seg_in_wnd(struct tcp_stream *tcp, + u32 tcp_seq_num, int payload_len) +{ + if ((payload_len == 0) && (tcp->rcv_wnd == 0)) { + if (tcp_seq_num == tcp->rcv_nxt) + return 1; + } + if ((payload_len == 0) && (tcp->rcv_wnd > 0)) { + if ((tcp_seq_cmp(tcp->rcv_nxt, tcp_seq_num) <= 0) && + (tcp_seq_cmp(tcp_seq_num, tcp->rcv_nxt + tcp->rcv_wnd) < 0)) + return 1; + } + if ((payload_len > 0) && (tcp->rcv_wnd > 0)) { + if ((tcp_seq_cmp(tcp->rcv_nxt, tcp_seq_num) <= 0) && + (tcp_seq_cmp(tcp_seq_num, tcp->rcv_nxt + tcp->rcv_wnd) < 0)) + return 1; + tcp_seq_num += payload_len - 1; + if ((tcp_seq_cmp(tcp->rcv_nxt, tcp_seq_num) <= 0) && + (tcp_seq_cmp(tcp_seq_num, tcp->rcv_nxt + tcp->rcv_wnd) < 0)) + return 1; + } + return 0; +} + +static int tcp_rx_check_ack_num(struct tcp_stream *tcp, u32 tcp_seq_num, + u32 tcp_ack_num, u32 tcp_win_size) +{ + u32 old_offs, new_offs; + u8 action; + + switch (tcp->state) { + case TCP_SYN_RECEIVED: + if ((tcp_seq_cmp(tcp->snd_una, tcp_ack_num) >= 0) || + (tcp_seq_cmp(tcp_ack_num, tcp->snd_nxt) > 0)) { + // segment acknowledgment is not acceptable + tcp_send_packet(tcp, TCP_RST, tcp_ack_num, 0, 0); + return TCP_PACKET_DROP; + } + + tcp_stream_set_state(tcp, TCP_ESTABLISHED); + tcp->snd_wnd = tcp_win_size; + tcp->snd_wl1 = tcp_seq_num; + tcp->snd_wl2 = tcp_ack_num; + + if (tcp->on_established != NULL) + tcp->on_established(tcp); + + fallthrough; + + case TCP_ESTABLISHED: + case TCP_FIN_WAIT_1: + case TCP_FIN_WAIT_2: + case TCP_CLOSE_WAIT: + case TCP_CLOSING: + if (tcp_seq_cmp(tcp_ack_num, tcp->snd_nxt) > 0) { + // ACK acks something not yet sent + action = tcp_stream_fin_needed(tcp, tcp->snd_una) | TCP_ACK; + tcp_send_packet(tcp, action, tcp->snd_una, tcp->rcv_nxt, 0); + return TCP_PACKET_DROP; + } + + if (tcp_seq_cmp(tcp->snd_una, tcp_ack_num) < 0) { + old_offs = tcp_stream_tx_offs(tcp); + tcp->snd_una = tcp_ack_num; + new_offs = tcp_stream_tx_offs(tcp); + if ((tcp->time_handler != NULL) && + (tcp_seq_cmp(tcp->snd_una, tcp->retry_seq_num) > 0)) { + tcp_stream_set_time_handler(tcp, 0, NULL); + } + if ((tcp->on_snd_una_update != NULL) && + (old_offs != new_offs)) + tcp->on_snd_una_update(tcp, new_offs); + } + + if (tcp_seq_cmp(tcp->snd_una, tcp_ack_num) <= 0) { + if ((tcp_seq_cmp(tcp->snd_wl1, tcp_seq_num) < 0) || + ((tcp->snd_wl1 == tcp_seq_num) && + (tcp_seq_cmp(tcp->snd_wl2, tcp_seq_num) <= 0))) { + tcp->snd_wnd = tcp_win_size; + tcp->snd_wl1 = tcp_seq_num; + tcp->snd_wl2 = tcp_ack_num; + } + } + + if (tcp->state == TCP_FIN_WAIT_1) { + if (tcp->snd_una == tcp->snd_nxt) + tcp_stream_set_state(tcp, TCP_FIN_WAIT_2); + } + + if (tcp->state == TCP_CLOSING) { + if (tcp->snd_una == tcp->snd_nxt) + tcp_stream_set_state(tcp, TCP_CLOSED); + } + return TCP_PACKET_OK; + + case TCP_LAST_ACK: + if (tcp_ack_num == tcp->snd_nxt) + tcp_stream_set_state(tcp, TCP_CLOSED); + return TCP_PACKET_OK; + + default: + return TCP_PACKET_DROP; + } +} + +static int tcp_rx_user_data(struct tcp_stream *tcp, u32 tcp_seq_num, + char *buf, int len) +{ + u32 tmp_len, buf_offs, old_offs, new_offs; + u8 action; + + if (len == 0) + return TCP_PACKET_OK; + + switch (tcp->state) { + case TCP_ESTABLISHED: + case TCP_FIN_WAIT_1: + case TCP_FIN_WAIT_2: + break; + default: + return TCP_PACKET_DROP; + } + + tmp_len = len; + old_offs = tcp_stream_rx_offs(tcp); + buf_offs = tcp_seq_num - tcp->irs - 1; + if (tcp->rx != NULL) + tmp_len = tcp->rx(tcp, buf_offs, buf, len); + if (tmp_len) + tcp_hole(tcp, tcp_seq_num, tmp_len); + + new_offs = tcp_stream_rx_offs(tcp); + if ((tcp->on_rcv_nxt_update != NULL) && (old_offs != new_offs)) + tcp->on_rcv_nxt_update(tcp, new_offs); + + action = tcp_stream_fin_needed(tcp, tcp->snd_una) | TCP_ACK; + tcp_send_packet(tcp, action, tcp->snd_una, tcp->rcv_nxt, 0); + return TCP_PACKET_OK; +} + +void tcp_rx_state_machine(struct tcp_stream *tcp, + union tcp_build_pkt *b, unsigned int pkt_len) { - u8 tcp_fin = tcp_flags & TCP_FIN; - u8 tcp_syn = tcp_flags & TCP_SYN; - u8 tcp_rst = tcp_flags & TCP_RST; - u8 tcp_push = tcp_flags & TCP_PUSH; - u8 tcp_ack = tcp_flags & TCP_ACK; - u8 action = TCP_DATA; + int tcp_len = pkt_len - IP_HDR_SIZE; + u32 tcp_seq_num, tcp_ack_num, tcp_win_size; + int tcp_hdr_len, payload_len; + u8 tcp_flags, action; + + tcp_hdr_len = GET_TCP_HDR_LEN_IN_BYTES(b->ip.hdr.tcp_hlen); + payload_len = tcp_len - tcp_hdr_len; + if (tcp_hdr_len > TCP_HDR_SIZE) + tcp_parse_options(tcp, (uchar *)b + IP_TCP_HDR_SIZE, + tcp_hdr_len - TCP_HDR_SIZE); /* - * tcp_flags are examined to determine TX action in a given state - * tcp_push is interpreted to mean "inform the app" - * urg, ece, cer and nonce flags are not supported. - * - * exe and crw are use to signal and confirm knowledge of congestion. - * This TCP only sends a file request and acks. If it generates - * congestion, the network is broken. + * Incoming sequence and ack numbers are server's view of the numbers. + * The app must swap the numbers when responding. */ - debug_cond(DEBUG_INT_STATE, "TCP STATE ENTRY %x\n", action); - if (tcp_rst) { - action = TCP_DATA; - tcp->state = TCP_CLOSED; - net_set_state(NETLOOP_FAIL); - debug_cond(DEBUG_INT_STATE, "TCP Reset %x\n", tcp_flags); - return TCP_RST; - } + tcp_seq_num = ntohl(b->ip.hdr.tcp_seq); + tcp_ack_num = ntohl(b->ip.hdr.tcp_ack); + tcp_win_size = ntohs(b->ip.hdr.tcp_win) << tcp->rmt_win_scale; - switch (tcp->state) { + tcp_flags = b->ip.hdr.tcp_flags; + +// printf("pkt: seq=%d, ack=%d, flags=%x, len=%d\n", +// tcp_seq_num - tcp->irs, tcp_ack_num - tcp->iss, tcp_flags, pkt_len); +// printf("tcp: rcv_nxt=%d, snd_una=%d, snd_nxt=%d\n\n", +// tcp->rcv_nxt - tcp->irs, tcp->snd_una - tcp->iss, tcp->snd_nxt - tcp->iss); + + switch (tcp->state) { case TCP_CLOSED: - debug_cond(DEBUG_INT_STATE, "TCP CLOSED %x\n", tcp_flags); - if (tcp_syn) { - action = TCP_SYN | TCP_ACK; - tcp->irs = tcp_seq_num; - tcp->rcv_nxt = tcp_seq_num + 1; - tcp->lost.len = TCP_OPT_LEN_2; - tcp->state = TCP_SYN_RECEIVED; - } else if (tcp_ack || tcp_fin) { - action = TCP_DATA; + if (tcp_flags & TCP_RST) + return; + + if (tcp_flags & TCP_ACK) { + tcp_send_packet(tcp, TCP_RST, tcp_ack_num, 0, 0); + return; } - break; - case TCP_SYN_RECEIVED: + + if (!(tcp_flags & TCP_SYN)) + return; + + tcp->irs = tcp_seq_num; + tcp->rcv_nxt = tcp->irs + 1; + + tcp->iss = tcp_get_start_seq(); + tcp->snd_una = tcp->iss; + tcp->snd_nxt = tcp->iss + 1; + tcp->snd_wnd = tcp_win_size; + + tcp->time_last_rx = get_timer(0); + + tcp_stream_set_state(tcp, TCP_SYN_RECEIVED); + tcp_send_packet_with_retry(tcp, TCP_SYN | TCP_ACK, + tcp->iss, 0, 0); + return; + case TCP_SYN_SENT: - debug_cond(DEBUG_INT_STATE, "TCP_SYN_SENT | TCP_SYN_RECEIVED %x, %u\n", - tcp_flags, tcp_seq_num); - if (tcp_fin) { - action = action | TCP_PUSH; - tcp->state = TCP_CLOSE_WAIT; - } else if (tcp_ack || (tcp_syn && tcp_ack)) { - action |= TCP_ACK; - tcp->irs = tcp_seq_num; - tcp->rcv_nxt = tcp_seq_num + 1; - tcp->state = TCP_ESTABLISHED; - - if (tcp_syn && tcp_ack) - action |= TCP_PUSH; - } else { - action = TCP_DATA; + if (!(tcp_flags & TCP_ACK)) + return; + + if ((tcp_seq_cmp(tcp_ack_num, tcp->iss) <= 0) || + (tcp_seq_cmp(tcp_ack_num, tcp->snd_nxt) > 0)) { + if (!(tcp_flags & TCP_RST)) + tcp_send_packet(tcp, TCP_RST, tcp_ack_num, 0, 0); + return; } - break; + + if (tcp_flags & TCP_RST) { + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_set_state(tcp, TCP_CLOSED); + return; + } + + if (!(tcp_flags & TCP_SYN)) + return; + + /* stop retransmit of SYN */ + tcp_stream_set_time_handler(tcp, 0, NULL); + + tcp->irs = tcp_seq_num; + tcp->rcv_nxt = tcp->irs + 1; + tcp->snd_una = tcp_ack_num; + + tcp->time_last_rx = get_timer(0); + + /* our SYN has been ACKed */ + tcp_stream_set_state(tcp, TCP_ESTABLISHED); + + if (tcp->on_established != NULL) + tcp->on_established(tcp); + + action = tcp_stream_fin_needed(tcp, tcp->snd_una) | TCP_ACK; + tcp_send_packet(tcp, action, tcp->snd_una, tcp->rcv_nxt, 0); + tcp_rx_user_data(tcp, tcp_seq_num, + ((char *)b) + pkt_len - payload_len, + payload_len); + return; + + case TCP_SYN_RECEIVED: case TCP_ESTABLISHED: - debug_cond(DEBUG_INT_STATE, "TCP_ESTABLISHED %x\n", tcp_flags); - if (payload_len > 0) { - tcp_hole(tcp, tcp_seq_num, payload_len); - tcp_fin = TCP_DATA; /* cause standalone FIN */ + case TCP_FIN_WAIT_1: + case TCP_FIN_WAIT_2: + case TCP_CLOSE_WAIT: + case TCP_CLOSING: + case TCP_LAST_ACK: + if (!tcp_seg_in_wnd(tcp, tcp_seq_num, payload_len)) { + if (tcp_flags & TCP_RST) + return; + action = tcp_stream_fin_needed(tcp, tcp->snd_una) | TCP_ACK; + tcp_send_packet(tcp, action, tcp->snd_una, tcp->rcv_nxt, 0); + return; } - if ((tcp_fin) && - (!IS_ENABLED(CONFIG_PROT_TCP_SACK) || - tcp->lost.len <= TCP_OPT_LEN_2)) { - action = action | TCP_FIN | TCP_PUSH | TCP_ACK; - tcp->state = TCP_CLOSE_WAIT; - } else if (tcp_ack) { - action = TCP_DATA; + tcp->time_last_rx = get_timer(0); + + if (tcp_flags & TCP_RST) { + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_set_state(tcp, TCP_CLOSED); + return; } - if (tcp_syn) - action = TCP_ACK + TCP_RST; - else if (tcp_push) - action = action | TCP_PUSH; - break; - case TCP_CLOSE_WAIT: - debug_cond(DEBUG_INT_STATE, "TCP_CLOSE_WAIT (%x)\n", tcp_flags); - action = TCP_DATA; - break; - case TCP_FIN_WAIT_2: - debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_2 (%x)\n", tcp_flags); - if (tcp_ack) { - action = TCP_PUSH | TCP_ACK; - tcp->state = TCP_CLOSED; - puts("\n"); - } else if (tcp_syn) { - action = TCP_DATA; - } else if (tcp_fin) { - action = TCP_DATA; + if (tcp_flags & TCP_SYN) { + tcp_send_packet(tcp, TCP_RST, tcp_ack_num, 0, 0); + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_set_state(tcp, TCP_CLOSED); + return; } - break; - case TCP_FIN_WAIT_1: - debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_1 (%x)\n", tcp_flags); - if (tcp_fin) { - tcp->rcv_nxt++; - action = TCP_ACK | TCP_FIN; - tcp->state = TCP_FIN_WAIT_2; + + if (!(tcp_flags & TCP_ACK)) + return; + + if (tcp_rx_check_ack_num(tcp, tcp_seq_num, tcp_ack_num, + tcp_win_size) == TCP_PACKET_DROP) { + return; } - if (tcp_syn) - action = TCP_RST; - if (tcp_ack) - tcp->state = TCP_CLOSED; - break; - case TCP_CLOSING: - debug_cond(DEBUG_INT_STATE, "TCP_CLOSING (%x)\n", tcp_flags); - if (tcp_ack) { - action = TCP_PUSH; - tcp->state = TCP_CLOSED; - puts("\n"); - } else if (tcp_syn) { - action = TCP_RST; - } else if (tcp_fin) { - action = TCP_DATA; + + if (tcp_rx_user_data(tcp, tcp_seq_num, + ((char *)b) + pkt_len - payload_len, + payload_len) == TCP_PACKET_DROP) { + return; + } + + if (tcp_flags & TCP_FIN) { + tcp->fin_rx = 1; + tcp->fin_rx_seq = tcp_seq_num + payload_len + 1; + tcp_hole(tcp, tcp_seq_num + payload_len, 1); + action = tcp_stream_fin_needed(tcp, tcp->snd_una) | TCP_ACK; + tcp_send_packet(tcp, action, tcp->snd_una, tcp->rcv_nxt, 0); + } + + if (tcp->fin_rx && (tcp->fin_rx_seq == tcp->rcv_nxt)) { + /* all rx data were processed */ + switch (tcp->state) { + case TCP_ESTABLISHED: + tcp_stream_set_state(tcp, TCP_LAST_ACK); + tcp_send_packet_with_retry(tcp, TCP_ACK | TCP_FIN, + tcp->snd_nxt, 0, 0); + tcp->snd_nxt++; + break; + + case TCP_FIN_WAIT_1: + if (tcp_ack_num == tcp->snd_nxt) + tcp_stream_set_state(tcp, TCP_CLOSED); + else + tcp_stream_set_state(tcp, TCP_CLOSING); + break; + + case TCP_FIN_WAIT_2: + tcp_stream_set_state(tcp, TCP_CLOSED); + break; + + default: + break; + } + } + + if ((tcp->state == TCP_FIN_WAIT_1) && + tcp_stream_fin_needed(tcp, tcp->snd_una)) { + /* all tx data were acknowledged */ + tcp_send_packet_with_retry(tcp, TCP_ACK | TCP_FIN, + tcp->snd_una, 0, 0); } - break; } - return action; } /** @@ -667,9 +1106,6 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) { int tcp_len = pkt_len - IP_HDR_SIZE; u16 tcp_rx_xsum = b->ip.hdr.ip_sum; - u8 tcp_action = TCP_DATA; - u32 tcp_seq_num, tcp_ack_num; - int tcp_hdr_len, payload_len; struct tcp_stream *tcp; struct in_addr src; @@ -713,54 +1149,57 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) if (tcp == NULL) return; - tcp_hdr_len = GET_TCP_HDR_LEN_IN_BYTES(b->ip.hdr.tcp_hlen); - payload_len = tcp_len - tcp_hdr_len; + tcp_rx_state_machine(tcp, b, pkt_len); + tcp_stream_put(tcp); +} - if (tcp_hdr_len > TCP_HDR_SIZE) - tcp_parse_options(tcp, (uchar *)b + IP_TCP_HDR_SIZE, - tcp_hdr_len - TCP_HDR_SIZE); - /* - * Incoming sequence and ack numbers are server's view of the numbers. - * The app must swap the numbers when responding. - */ - tcp_seq_num = ntohl(b->ip.hdr.tcp_seq); - tcp_ack_num = ntohl(b->ip.hdr.tcp_ack); +struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport) +{ + struct tcp_stream *tcp; - /* Packets are not ordered. Send to app as received. */ - tcp_action = tcp_state_machine(tcp, b->ip.hdr.tcp_flags, - tcp_seq_num, payload_len); + tcp = tcp_stream_add(rhost, rport, random_port()); + if (tcp == NULL) + return NULL; - tcp_activity_count++; - if (tcp_activity_count > TCP_ACTIVITY) { - puts("| "); - tcp_activity_count = 0; - } + tcp->iss = tcp_get_start_seq(); + tcp->snd_una = tcp->iss; + tcp->snd_nxt = tcp->iss + 1; - if ((tcp_action & TCP_PUSH) || payload_len > 0) { - debug_cond(DEBUG_DEV_PKT, - "TCP Notify (action=%x, Seq=%u,Ack=%u,Pay%d)\n", - tcp_action, tcp_seq_num, tcp_ack_num, payload_len); + tcp_stream_set_state(tcp, TCP_SYN_SENT); + tcp_send_packet_with_retry(tcp, TCP_SYN, tcp->snd_una, 0, 0); + return tcp; +} - (*tcp_packet_handler) (tcp, (uchar *)b + pkt_len - payload_len, - tcp_seq_num, tcp_ack_num, tcp_action, - payload_len); +void tcp_stream_reset(struct tcp_stream *tcp) +{ + if (tcp->state == TCP_CLOSED) + return; - } else if (tcp_action != TCP_DATA) { - debug_cond(DEBUG_DEV_PKT, - "TCP Action (action=%x,Seq=%u,Ack=%u,Pay=%d)\n", - tcp_action, tcp_ack_num, tcp->rcv_nxt, payload_len); - - /* - * Warning: Incoming Ack & Seq sequence numbers are transposed - * here to outgoing Seq & Ack sequence numbers - */ - net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, - (tcp_action & (~TCP_PUSH)), - tcp_ack_num, tcp->rcv_nxt); - } + tcp_stream_set_time_handler(tcp, 0, NULL); + tcp_send_packet(tcp, TCP_RST, tcp->snd_una, 0, 0); + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_set_state(tcp, TCP_CLOSED); } -struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport) +void tcp_stream_close(struct tcp_stream *tcp) { - return tcp_stream_add(rhost, rport, random_port()); + switch (tcp->state) { + case TCP_SYN_SENT: + tcp_stream_reset(tcp); + break; + case TCP_SYN_RECEIVED: + case TCP_ESTABLISHED: + tcp->fin_tx = 1; + tcp->fin_tx_seq = tcp->snd_nxt; + if (tcp_stream_fin_needed(tcp, tcp->snd_una)) { + /* all tx data were acknowledged */ + tcp_send_packet_with_retry(tcp, TCP_ACK | TCP_FIN, + tcp->snd_una, 0, 0); + } + tcp_stream_set_state(tcp, TCP_FIN_WAIT_1); + tcp->snd_nxt++; + break; + default: + break; + } } diff --git a/net/wget.c b/net/wget.c index ad5db21e97e..ba95efa61c1 100644 --- a/net/wget.c +++ b/net/wget.c @@ -21,48 +21,26 @@ DECLARE_GLOBAL_DATA_PTR; /* The default, change with environment variable 'httpdstp' */ #define SERVER_PORT 80 +#define HASHES_PER_LINE 65 + +#define HTTP_MAX_HDR_LEN 2048 + static const char bootfile1[] = "GET "; static const char bootfile3[] = " HTTP/1.0\r\n\r\n"; static const char http_eom[] = "\r\n\r\n"; -static const char http_ok[] = "200"; -static const char content_len[] = "Content-Length"; +static const char http_ok[] = " 200 "; +static const char content_len[] = "Content-Length:"; static const char linefeed[] = "\r\n"; -static int wget_timeout_count; -struct tcp_stream *tcp; - -struct pkt_qd { - uchar *pkt; - unsigned int tcp_seq_num; - unsigned int len; -}; - -/* - * This is a control structure for out of order packets received. - * The actual packet bufers are in the kernel space, and are - * expected to be overwritten by the downloaded image. - */ -#define PKTQ_SZ (PKTBUFSRX / 4) -static struct pkt_qd pkt_q[PKTQ_SZ]; -static int pkt_q_idx; +static struct in_addr web_server_ip; +static unsigned int server_port; static unsigned long content_length; static unsigned int packets; - -static unsigned int initial_data_seq_num; -static unsigned int next_data_seq_num; - -static enum wget_state current_wget_state; +static u32 http_hdr_size; +static int wget_tsize_num_hash; static char *image_url; -static unsigned int wget_timeout = WGET_TIMEOUT; - static enum net_loop_state wget_loop_state; -/* Timeout retry parameters */ -static u8 retry_action; /* actions for TCP retry */ -static unsigned int retry_tcp_ack_num; /* TCP retry acknowledge number*/ -static unsigned int retry_tcp_seq_num; /* TCP retry sequence number */ -static int retry_len; /* TCP retry length */ - static ulong wget_load_size; /** @@ -95,7 +73,6 @@ static int wget_init_load_size(void) static inline int store_block(uchar *src, unsigned int offset, unsigned int len) { ulong store_addr = image_load_addr + offset; - ulong newsize = offset + len; uchar *ptr; if (IS_ENABLED(CONFIG_LMB)) { @@ -115,330 +92,150 @@ static inline int store_block(uchar *src, unsigned int offset, unsigned int len) ptr = map_sysmem(store_addr, len); memcpy(ptr, src, len); unmap_sysmem(ptr); - - if (net_boot_file_size < (offset + len)) - net_boot_file_size = newsize; - return 0; } -/** - * wget_send_stored() - wget response dispatcher - * - * WARNING, This, and only this, is the place in wget.c where - * SEQUENCE NUMBERS are swapped between incoming (RX) - * and outgoing (TX). - * Procedure wget_handler() is correct for RX traffic. - */ -static void wget_send_stored(void) +static void show_block_marker(void) { - u8 action = retry_action; - int len = retry_len; - unsigned int tcp_ack_num = retry_tcp_seq_num + (len == 0 ? 1 : len); - unsigned int tcp_seq_num = retry_tcp_ack_num; - uchar *ptr, *offset; - - switch (current_wget_state) { - case WGET_CLOSED: - debug_cond(DEBUG_WGET, "wget: send SYN\n"); - current_wget_state = WGET_CONNECTING; - net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, action, - tcp_seq_num, tcp_ack_num); - packets = 0; - break; - case WGET_CONNECTING: - pkt_q_idx = 0; - net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, action, - tcp_seq_num, tcp_ack_num); - - ptr = net_tx_packet + net_eth_hdr_size() + - IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; - offset = ptr; - - memcpy(offset, &bootfile1, strlen(bootfile1)); - offset += strlen(bootfile1); - - memcpy(offset, image_url, strlen(image_url)); - offset += strlen(image_url); - - memcpy(offset, &bootfile3, strlen(bootfile3)); - offset += strlen(bootfile3); - net_send_tcp_packet((offset - ptr), tcp->rhost, tcp->rport, tcp->lport, - TCP_PUSH, tcp_seq_num, tcp_ack_num); - current_wget_state = WGET_CONNECTED; - break; - case WGET_CONNECTED: - case WGET_TRANSFERRING: - case WGET_TRANSFERRED: - net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, action, - tcp_seq_num, tcp_ack_num); - break; - } -} + int cnt; -static void wget_send(u8 action, unsigned int tcp_seq_num, - unsigned int tcp_ack_num, int len) -{ - retry_action = action; - retry_tcp_ack_num = tcp_ack_num; - retry_tcp_seq_num = tcp_seq_num; - retry_len = len; + if (content_length != -1) { + if (net_boot_file_size > content_length) + content_length = net_boot_file_size; - wget_send_stored(); + cnt = net_boot_file_size * 50 / content_length; + while (wget_tsize_num_hash < cnt) { + putc('#'); + wget_tsize_num_hash++; + } + } else { + if ((packets % 10) == 0) + putc('#'); + else if (((packets + 1) % (10 * HASHES_PER_LINE)) == 0) + puts("\n"); + } } -void wget_fail(char *error_message, unsigned int tcp_seq_num, - unsigned int tcp_ack_num, u8 action) +static void tcp_stream_on_closed(struct tcp_stream *tcp) { - printf("wget: Transfer Fail - %s\n", error_message); - net_set_timeout_handler(0, NULL); - wget_send(action, tcp_seq_num, tcp_ack_num, 0); + if (tcp->status != TCP_ERR_OK) + wget_loop_state = NETLOOP_FAIL; + + if (wget_loop_state != NETLOOP_SUCCESS) + printf("\nwget: Transfer Fail, TCP status - %d\n", tcp->status); + else + printf("\nPackets received %d, Transfer Successful\n", packets); + net_set_state(wget_loop_state); } -void wget_success(u8 action, unsigned int tcp_seq_num, - unsigned int tcp_ack_num, int len, int packets) +static void tcp_stream_on_rcv_nxt_update(struct tcp_stream *tcp, u32 rx_bytes) { - printf("Packets received %d, Transfer Successful\n", packets); - wget_send(action, tcp_seq_num, tcp_ack_num, len); -} + char *pos, *tail; + uchar saved, *ptr; + int i; -/* - * Interfaces of U-BOOT - */ -static void wget_timeout_handler(void) -{ - if (++wget_timeout_count > WGET_RETRY_COUNT) { - puts("\nRetry count exceeded; starting again\n"); - wget_send(TCP_RST, 0, 0, 0); - net_start_again(); - } else { - puts("T "); - net_set_timeout_handler(wget_timeout + - WGET_TIMEOUT * wget_timeout_count, - wget_timeout_handler); - wget_send_stored(); + if (http_hdr_size != 0) { + net_boot_file_size = rx_bytes - http_hdr_size; + show_block_marker(); + return; } -} -#define PKT_QUEUE_OFFSET 0x20000 -#define PKT_QUEUE_PACKET_SIZE 0x800 + ptr = map_sysmem(image_load_addr, rx_bytes + 1); -static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, - u8 action, unsigned int tcp_ack_num, unsigned int len) -{ - uchar *pkt_in_q; - char *pos; - int hlen, i; - uchar *ptr1; + saved = ptr[rx_bytes]; + ptr[rx_bytes] = '\0'; + pos = strstr((char *)ptr, http_eom); + ptr[rx_bytes] = saved; - pkt[len] = '\0'; - pos = strstr((char *)pkt, http_eom); + if (pos == NULL) { + if ((rx_bytes < HTTP_MAX_HDR_LEN) && + (tcp->state == TCP_ESTABLISHED)) + goto end; - if (!pos) { - debug_cond(DEBUG_WGET, - "wget: Connected, data before Header %p\n", pkt); - pkt_in_q = (void *)image_load_addr + PKT_QUEUE_OFFSET + - (pkt_q_idx * PKT_QUEUE_PACKET_SIZE); - - ptr1 = map_sysmem((phys_addr_t)pkt_in_q, len); - memcpy(ptr1, pkt, len); - unmap_sysmem(ptr1); - - pkt_q[pkt_q_idx].pkt = pkt_in_q; - pkt_q[pkt_q_idx].tcp_seq_num = tcp_seq_num; - pkt_q[pkt_q_idx].len = len; - pkt_q_idx++; - - if (pkt_q_idx >= PKTQ_SZ) { - printf("wget: Fatal error, queue overrun!\n"); - net_set_state(NETLOOP_FAIL); + printf("ERROR: misssed HTTP header\n"); + tcp_stream_close(tcp); + wget_loop_state = NETLOOP_FAIL; + goto end; + } - return; - } - } else { - debug_cond(DEBUG_WGET, "wget: Connected HTTP Header %p\n", pkt); - /* sizeof(http_eom) - 1 is the string length of (http_eom) */ - hlen = pos - (char *)pkt + sizeof(http_eom) - 1; - pos = strstr((char *)pkt, linefeed); - if (pos > 0) - i = pos - (char *)pkt; - else - i = hlen; - printf("%.*s", i, pkt); - - current_wget_state = WGET_TRANSFERRING; - - initial_data_seq_num = tcp_seq_num + hlen; - next_data_seq_num = tcp_seq_num + len; - - if (strstr((char *)pkt, http_ok) == 0) { - debug_cond(DEBUG_WGET, - "wget: Connected Bad Xfer\n"); - wget_loop_state = NETLOOP_FAIL; - wget_send(action, tcp_seq_num, tcp_ack_num, len); - } else { - debug_cond(DEBUG_WGET, - "wget: Connctd pkt %p hlen %x\n", - pkt, hlen); - - pos = strstr((char *)pkt, content_len); - if (!pos) { - content_length = -1; - } else { - pos += sizeof(content_len) + 2; - strict_strtoul(pos, 10, &content_length); - debug_cond(DEBUG_WGET, - "wget: Connected Len %lu\n", - content_length); - } - - net_boot_file_size = 0; - - if (len > hlen) { - if (store_block(pkt + hlen, 0, len - hlen) != 0) { - wget_loop_state = NETLOOP_FAIL; - wget_fail("wget: store error\n", tcp_seq_num, tcp_ack_num, action); - net_set_state(NETLOOP_FAIL); - return; - } - } + http_hdr_size = pos - (char *)ptr + strlen(http_eom); + *pos = '\0'; + + pos = strstr((char *)ptr, linefeed); + if (pos > 0) + i = pos - (char *)ptr; + else + i = http_hdr_size - strlen(http_eom); + printf("%.*s\n", i, ptr); + + if (strstr((char *)ptr, http_ok) == NULL) { + debug_cond(DEBUG_WGET, "wget: Connected Bad Xfer\n"); + tcp_stream_close(tcp); + wget_loop_state = NETLOOP_FAIL; + goto end; + } - debug_cond(DEBUG_WGET, - "wget: Connected Pkt %p hlen %x\n", - pkt, hlen); - - for (i = 0; i < pkt_q_idx; i++) { - int err; - - ptr1 = map_sysmem( - (phys_addr_t)(pkt_q[i].pkt), - pkt_q[i].len); - err = store_block(ptr1, - pkt_q[i].tcp_seq_num - - initial_data_seq_num, - pkt_q[i].len); - unmap_sysmem(ptr1); - debug_cond(DEBUG_WGET, - "wget: Connctd pkt Q %p len %x\n", - pkt_q[i].pkt, pkt_q[i].len); - if (err) { - wget_loop_state = NETLOOP_FAIL; - wget_fail("wget: store error\n", tcp_seq_num, tcp_ack_num, action); - net_set_state(NETLOOP_FAIL); - return; - } - } - } + debug_cond(DEBUG_WGET, "wget: Connctd pkt %p hlen %x\n", + ptr, http_hdr_size); + + pos = strstr((char *)ptr, content_len); + if (!pos) { + content_length = -1; + } else { + pos += strlen(content_len) + 1; + content_length = simple_strtoul(pos, &tail, 10); + if ((*tail != '\r') && (*tail != '\n') && (*tail != '\0')) + content_length = -1; + printf("%s %d\n", content_len, (int)content_length); } - wget_send(action, tcp_seq_num, tcp_ack_num, len); + + net_boot_file_size = rx_bytes - http_hdr_size; + memmove(ptr, ptr + http_hdr_size, net_boot_file_size); + +end: + unmap_sysmem(ptr); + + wget_loop_state = NETLOOP_SUCCESS; } -/** - * wget_handler() - TCP handler of wget - * @tcp: TCP stream - * @pkt: pointer to the application packet - * @tcp_seq_num: TCP sequential number - * @tcp_ack_num: TCP acknowledgment number - * @action: TCP action (SYN, ACK, FIN, etc) - * @len: packet length - * - * In the "application push" invocation, the TCP header with all - * its information is pointed to by the packet pointer. - */ -static void wget_handler(struct tcp_stream *tcp, uchar *pkt, - u32 tcp_seq_num, u32 tcp_ack_num, - u8 action, unsigned int len) +static u32 tcp_stream_rx(struct tcp_stream *tcp, u32 rx_offs, void *buf, u32 len) { - enum tcp_state wget_tcp_state = tcp_stream_get_state(tcp); - - net_set_timeout_handler(wget_timeout, wget_timeout_handler); packets++; + store_block(buf, rx_offs - http_hdr_size, len); + return len; +} - switch (current_wget_state) { - case WGET_CLOSED: - debug_cond(DEBUG_WGET, "wget: Handler: Error!, State wrong\n"); - break; - case WGET_CONNECTING: - debug_cond(DEBUG_WGET, - "wget: Connecting In len=%x, Seq=%u, Ack=%u\n", - len, tcp_seq_num, tcp_ack_num); - if (!len) { - if (wget_tcp_state == TCP_ESTABLISHED) { - debug_cond(DEBUG_WGET, - "wget: Cting, send, len=%x\n", len); - wget_send(action, tcp_seq_num, tcp_ack_num, - len); - } else { - printf("%.*s", len, pkt); - wget_fail("wget: Handler Connected Fail\n", - tcp_seq_num, tcp_ack_num, action); - } - } - break; - case WGET_CONNECTED: - debug_cond(DEBUG_WGET, "wget: Connected seq=%u, len=%x\n", - tcp_seq_num, len); - if (!len) { - wget_fail("Image not found, no data returned\n", - tcp_seq_num, tcp_ack_num, action); - } else { - wget_connected(pkt, tcp_seq_num, action, tcp_ack_num, len); - } - break; - case WGET_TRANSFERRING: - debug_cond(DEBUG_WGET, - "wget: Transferring, seq=%x, ack=%x,len=%x\n", - tcp_seq_num, tcp_ack_num, len); - - if (next_data_seq_num != tcp_seq_num) { - debug_cond(DEBUG_WGET, "wget: seq=%x packet was lost\n", next_data_seq_num); - return; - } - next_data_seq_num = tcp_seq_num + len; +static u32 tcp_stream_tx(struct tcp_stream *tcp, u32 tx_offs, void *buf, u32 maxlen) +{ + int ret; - if (store_block(pkt, tcp_seq_num - initial_data_seq_num, len) != 0) { - wget_fail("wget: store error\n", - tcp_seq_num, tcp_ack_num, action); - net_set_state(NETLOOP_FAIL); - return; - } + if (tx_offs != 0) + return 0; - switch (wget_tcp_state) { - case TCP_FIN_WAIT_2: - wget_send(TCP_ACK, tcp_seq_num, tcp_ack_num, len); - fallthrough; - case TCP_SYN_SENT: - case TCP_SYN_RECEIVED: - case TCP_CLOSING: - case TCP_FIN_WAIT_1: - case TCP_CLOSED: - net_set_state(NETLOOP_FAIL); - break; - case TCP_ESTABLISHED: - wget_send(TCP_ACK, tcp_seq_num, tcp_ack_num, - len); - wget_loop_state = NETLOOP_SUCCESS; - break; - case TCP_CLOSE_WAIT: /* End of transfer */ - current_wget_state = WGET_TRANSFERRED; - wget_send(action | TCP_ACK | TCP_FIN, - tcp_seq_num, tcp_ack_num, len); - break; - } - break; - case WGET_TRANSFERRED: - printf("Packets received %d, Transfer Successful\n", packets); - net_set_state(wget_loop_state); - break; - } + ret = snprintf(buf, maxlen, "%s%s%s", bootfile1, image_url, bootfile3); + return ret; +} + +static int tcp_stream_on_create(struct tcp_stream *tcp) +{ + if ((tcp->rhost.s_addr != web_server_ip.s_addr) || + (tcp->rport != server_port)) + return 0; + + tcp->max_retry_count = WGET_RETRY_COUNT; + tcp->initial_timeout = WGET_TIMEOUT; + tcp->on_closed = tcp_stream_on_closed; + tcp->on_rcv_nxt_update = tcp_stream_on_rcv_nxt_update; + tcp->rx = tcp_stream_rx; + tcp->tx = tcp_stream_tx; + return 1; } #define BLOCKSIZE 512 void wget_start(void) { - struct in_addr web_server_ip; - unsigned int server_port; + struct tcp_stream *tcp; image_url = strchr(net_boot_file_name, ':'); if (image_url > 0) { @@ -486,12 +283,6 @@ void wget_start(void) } } - net_set_timeout_handler(wget_timeout, wget_timeout_handler); - tcp_set_tcp_handler(wget_handler); - - wget_timeout_count = 0; - current_wget_state = WGET_CLOSED; - /* * Zero out server ether to force arp resolution in case * the server ip for the previous u-boot command, for example dns @@ -500,14 +291,21 @@ void wget_start(void) memset(net_server_ethaddr, 0, 6); + packets = 0; + net_boot_file_size = 0; + http_hdr_size = 0; + wget_tsize_num_hash = 0; + wget_loop_state = NETLOOP_FAIL; + server_port = env_get_ulong("httpdstp", 10, SERVER_PORT) & 0xffff; + tcp_stream_set_on_create_handler(tcp_stream_on_create); tcp = tcp_stream_connect(web_server_ip, server_port); if (tcp == NULL) { + printf("No free tcp streams\n"); net_set_state(NETLOOP_FAIL); return; } - - wget_send(TCP_SYN, 0, 0, 0); + tcp_stream_put(tcp); } #if (IS_ENABLED(CONFIG_CMD_DNS)) From patchwork Fri Aug 23 20:45:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1976259 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=TrvM/6it; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WrBv075LQz1yXY for ; Sat, 24 Aug 2024 06:46:36 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 3555B88C42; Fri, 23 Aug 2024 22:45:41 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b="TrvM/6it"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 17A2D88B23; Fri, 23 Aug 2024 22:45:39 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-VI1-obe.outbound.protection.outlook.com (mail-vi1eur02on2072f.outbound.protection.outlook.com [IPv6:2a01:111:f403:2607::72f]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 1BB7188BD2 for ; Fri, 23 Aug 2024 22:45:37 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=J5jfRSPw6EEFYT6Tzb8X4hREVGl55UIRK5qzq8tq1kbFHAC6OxAirVajb0LEy86Z7otVoHVMeOl492wt4Z5SmnkX47eq7t1yUJJg4vzo1E+yupyMFdL/V80GZ1+Wjvk7lgPawb53STjlh/Z3MyjcmI9XgQKZde6PL/QysfR0TyWjrvxe3PuEblSQ4cYw2z8ImWop6w5ydc1ewGnLjQ8v2BqqkrAvA2bEIct++daMjnDDo4fxvd+6U01FlS+nXa/bGJiy8IMfuQgRg3NRBJM3dxaGsRsyCYbZWPBgUlqtTiv/kLxRmVISNjGwXWNt3CyKZrdkdtC/69sdyb4gEXA0Rw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=fvJUazOHoQsPXDqSQ4ygdMPO6cxF2XXx5JLh0nnKsZE=; b=ywkhu434nUFC88crJJNPep+/Ogtd4MHYRFJC03wSV2Qg0KKraTC2eWoAxlOogrmxTQ4ZXLTgZ2yfya3/JFiksWQm7BDq5V0uVvvzfQ1kNNLnHoI7h5GUtz4vCGtTTQPzb7mmMXV518L1SWFTX9lui6Yduo3UiwfPZCvTjbtV94rEqcmXrLtXWItgzKQJxhTM68DLYBFKLU6ENn6UxTEGXcU3w8MCFMiXeKJMkJLjs9on8Bq8f/keH6h8Wg5JLjFT8E4Tc1swibBWij8Z3teWE8L0Iq9H6URC546t1dlzsLpgYudwTnEAN7Wd0yWrcr/YQfJm9juJanRoyS33FhgD2g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu; dkim=pass header.d=iopsys.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fvJUazOHoQsPXDqSQ4ygdMPO6cxF2XXx5JLh0nnKsZE=; b=TrvM/6it9E5nbM26UeZSLFmnWY2eOISMLQxc+pikjACwZVj/wo4d7dA1haZ8JGHVdluIo6g1wnaHt+5taUHms/MIOmSKjJMoEIHnPzUelNj1/JO4F0G9kyxQk6sDqs+mqgzkDLn4KFIjhx2yI24I0yXj+VLsB1JPd+HcGIiwnoCk44KbzP7Z8MHRyyho+BJ6kzYqDqRCUiiG+PBMfciKkdsovIgM1beX5wZM+1XerTtRD1Cr43SBXYJo9F0bqoIjp/fEWMTn1t/I1piZ97bSns73nmGs30obHGltqBpyG8sNWsbUWv38WnhY9tm4xC6ewQ/WGWr+1ygwq4N1LYDOYQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=iopsys.eu; Received: from GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) by VI0PR08MB11224.eurprd08.prod.outlook.com (2603:10a6:800:251::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.12; Fri, 23 Aug 2024 20:45:36 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7897.010; Fri, 23 Aug 2024 20:45:36 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Yasuharu Shibata , u-boot@lists.denx.de Subject: [PATCH v4 7/9] net/tcp: simplify tcp header filling code Date: Fri, 23 Aug 2024 23:45:16 +0300 Message-ID: <20240823204518.1010194-8-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> References: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR4P281CA0373.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f8::20) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB11224:EE_ X-MS-Office365-Filtering-Correlation-Id: 7535667a-c693-4792-558d-08dcc3b48a19 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|7416014|52116014|376014|1800799024|38350700014|921020; X-Microsoft-Antispam-Message-Info: E1/DsQv4Pve+9iJKooWnQ6/qjn9V9JxympA8fOVcFCwkB4iIOisGZx9jI87dZ17Jp+aLyc75uOr2rU3s4/Ir+BSi4VC2FG7Wl38IYu1ve3zNhvMQeYHjSy+fTltGWc6wbpzuXdfDZvIKFRRgkhloY9EKGkMJrTS3S1gB9OxZjI+vsdwZvRm/B752y1Iax90tkF/wOeP5QFz8n3LUOlLbUInxKTE2/scY0njcEhMTl9Ocdd6aHN15ahZnHHJItxoMFLh6nIpigk/KA41MNDZ2qdZjFlimXa7QeO2k7qfeJoYqHs1Mo4qMjoceimfv0twc4bEdjvruSEgUp80JYAKOn/D8A7Ku/36ePvimJggnctGq9SFSeMOVARakD1JthJeFEKEVijroCTVOvwa9Isip4djmXgFANZqPLhfJ1KyhdWFbhVedT+P9QGNun5vFggmyP0JJCuy5zOXbWVpYw3Y3oCW0ZLu2yOup09WXzY+nJsZb7py/Gc5fN2fKM+Dv1GXlrcsnx2gxpIrYWEo3ZK5HVTsh6hK+xPMDlLIUdozDEmS8S6zn14HfGKUWl7ivDBXkIPt6aep2DmuznEGC4z4TcR6dn2p5uxoSA9F9AultkDqr+FNMpcd3Pyj+fUqZGdTMv+7T6e2a1B9L46ZtalaWNtYKs6mh2JeQQFmiVmqNaDpGjKZ5pm+Hlcuj7EjpOhcWAasC7Rj7PvO8YIxhBzqz4T+/LAWLhX6640wHcLnRqfA6tDnVkIUJT7jXFb0DykL5LUzFIzZkvy/wVTfdUhmoFLUncWCTg0MO0ZYvgo366YLaj7DvbP8/j36GNQPcbqJeJ1JSIeIFabJvzf1bqnyJQZsz0KNsyeJqy8d6M2HPdDY73rEUnDafyd7VDR0DpXfwabnG4Mkn+AzSUo5l+ruXxZxamEbv5u878tcMCHzNLBxy4pIKIRy9DwkQmUVzSgFd8ziMea/kCxhtTNOOifUhCb+DszWVtOMVP7QwkAUNk5fE34oToQE166+ltZL6JsDdmRAhxvrDGxutF1+co0YNKF7H3rF/9LhepG9In0f90I14YXbtPQpSt2PGGY1ggMM91vQL73i3Dh58i4x46hG+7onKkGWi/smWD2cb1o/uJid242qC5MLuu89eOlehWHm1JDMD0JEqRGGd0mSWi8gvjnBdr/wssZtV6GM5Lt/vqxa0McK0ivy8rANrTpCqhFO9UrTqWV/BYRSlw4l2eYrTcrrvavw1d710USbsn6jyugDzvrIf+D1udgqYhAX+5g6nCr9Pm+SxCcKmqhn3tolmPlcKVxGWOee6FNCK6GFhqVev6mCHfCA1HtdOusMVLdu8HsQc75FLThBoNG5ptrayiQLT+QZu74S6Ce14FaOaZmDl020ab8ClC+8uJMPuLXS3G7bwczd9Qf8LsKDla5yn7UP6ggGaaD7S8J6RlUnU36k= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(7416014)(52116014)(376014)(1800799024)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 0csyJ9MeymHwhnZkgnn4cemOSrw8enaBq5ap2VLv+ZWcierdWde5M3IPRFdmoGV/P6CrucvLYi1Irhf14d+lT1nGiOwvopsYNhWBqW4hfb7N+o+RDcDsqTanhiEqZYNfOP5jlt50xGRwImDVAon3ESjNT67S1TaNxyqJ3N123D6YRwjq/JKwHJ1M9Jub1JYoQJB6VBtCrEdwi5vYMutu9CnKh6c5fuzvtWRSUUQzZ9SkoduE7r8ZEuv9h1j6rzIhAKy6faQ0S43kDffQlWw5Iy0Wq4IDzKYG32NBEvv1xNJuqq1Cf/XlqInNM7JhQywOKhYSfQdXCiks4N/p+nNKPWC3ZOpuwV6Vr0/wXpuD1XTShP3Nr9Uvhmh8KVG8pezFmNRvQdOYFJ+20i8Kk94fEd9fmvOKDEoM/MJbsJq0FkLL2Tix1YemxsFxzNMcTwzYTftre4mwTq8kAJCPr8V0JM/weF+UOnYkSpaMx03N4moc9NpNE3UI0hE40Ft1wP8MJ9XNdDmNv5dcCuEwTvj4jp6/lZDMv3p6+/7YoEW5KgNlaEJ4nAzFzsluIfmjB7s5C0DrWI2Xo+zexwBTx/2TE0fAl2UnDqIfbfO05OHyGTqcv4dnwQjVWHH51GNMW/kwXgVOM8oqK1P7IrtDA0WsAqA3Eqm+3A9fj9UYiomsEacob97oxVwxdwsf/gv+aynVz5ddYfwPFk9cQ1lAYypVd3C/0dcpCt5zrAYSjZx8oSPC+bEVhuGS2CgEeo0/HfIqitg1xysQWbkvIKG9EIOBilqrRq+tEs5of2r8hpnYLZq08lU+2Hoa1jbojVbBEMLYrXp0gpHSX6G4RdSBUvJQ3VxYK/pyxpVDBSBxEU77n5UngHOB7FDx6ycBHWRLu04LqFJmTFGbBuQ+3689utiKtqkCBQF8cI9ZXI99oIdwxSbfHTakXvkBswfSzxTqOMWV7YBDXPm2mRqARM58umUATxHn00UkYkkJ/DilRePIX1iAl07D+kzRmdyWNE167fd6jAo6K/hLploSWZ7zTt67SAdbrbbpZsZpCigdfuyenkYahTYd/nEPKGmw2cQ1oiIGX0dXYspLRF0BjB0WuMg1nH4AuAY8s9kcxkaLAZ9VF4bWHi7m7OeRklt8YUXap1KHy4Gkocmw/ThbesUJrrr1axqWE1BQGVM6XVnsfj6EzsrbF5jWU0e1QHlOvucQPf38veEVpJk4fg6CUzu42D+5eSdnJdqmsL4yOfN2PGW/wbdedFQTbsX8OT1ZT6U/gtyfPOzflDmKTIwrWWlaonNStvpfLJe+1Mnez0DH9jo5qxWsyMvDZnstok3a2u4D5p3Rdim4picWLVGBMvn+Zy/JT76X/Yu59Thxci0iYwzXuKP2rBZtfg2y+y1Qjt8AagPi4sAq6MuMFcnRcY7zfkGBKTzq0VwlltYMHcdESTb9OaSUEXkI/ggpIZuCpzVBS1MGTWXGcdJKIJLUA+B/wSYnHkyZpUt52744cTR7Mof7r1fKRqV1vkzTK2u6PvNjHfuY28/G6bplRBIBMLpMO7yj2pqmXWWs+BZMRp7HEh9AdnpHfrxVM/1E1Mc1Dh09Tv5uentJ9ItRRfTY3B9PFBP0snHEgKlW9N1DZ1MqmNHFp/c= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 7535667a-c693-4792-558d-08dcc3b48a19 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Aug 2024 20:45:35.9408 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8d891be1-7bce-4216-9a99-bee9de02ba58 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: bHm9R/CF4QuYm7fwbsejSaJRTvNqqr9t3sjjiK6liBCGXc78YWU0yDJeRlO/pt18xHZ/7ys8msG4VO2EbFVQF0L3Tt7VwDGUqvpvVDm4OMQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB11224 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- net/tcp.c | 70 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/net/tcp.c b/net/tcp.c index 2c34556c26d..7014d5b4f43 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -527,10 +527,37 @@ void net_set_syn_options(struct tcp_stream *tcp, union tcp_build_pkt *b) b->ip.end = TCP_O_END; } +const char *tcpflags_to_str(char tcpflags, char *buf, int size) +{ + int i = 0, len; + char *orig = buf; + const struct { + int bit; + const char *name; + } desc[] = {{TCP_RST, "RST"}, {TCP_SYN, "SYN"}, {TCP_PUSH, "PSH"}, + {TCP_FIN, "FIN"}, {TCP_ACK, "ACK"}, {0, NULL}}; + + *orig = '\0'; + while (desc[i].name != NULL) { + len = strlen(desc[i].name); + if (size <= len + 1) + break; + if (buf != orig) { + *buf++ = ','; + size--; + } + strcpy(buf, desc[i].name); + buf += len; + size -= len; + } + return orig; +} + int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num) { union tcp_build_pkt *b = (union tcp_build_pkt *)pkt; + char buf[24]; int pkt_hdr_len; int pkt_len; int tcp_len; @@ -540,55 +567,32 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, * 4 bits reserved options */ b->ip.hdr.tcp_flags = action; - pkt_hdr_len = IP_TCP_HDR_SIZE; b->ip.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); switch (action) { case TCP_SYN: debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:SYN (%pI4, %pI4, sq=%u, ak=%u)\n", - &tcp->rhost, &net_ip, - tcp_seq_num, tcp_ack_num); + "TCP Hdr:%s (%pI4, %pI4, s=%u, a=%u)\n", + tcpflags_to_str(action, buf, sizeof(buf)), + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); net_set_syn_options(tcp, b); pkt_hdr_len = IP_TCP_O_SIZE; break; - case TCP_SYN | TCP_ACK: - case TCP_ACK: - pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(tcp, b); - b->ip.hdr.tcp_flags = action; - debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:ACK (%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num, - action); - break; - case TCP_FIN: - debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:FIN (%pI4, %pI4, s=%u, a=%u)\n", - &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); - payload_len = 0; - pkt_hdr_len = IP_TCP_HDR_SIZE; - break; case TCP_RST | TCP_ACK: case TCP_RST: debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:RST (%pI4, %pI4, s=%u, a=%u)\n", + "TCP Hdr:%s (%pI4, %pI4, s=%u, a=%u)\n", + tcpflags_to_str(action, buf, sizeof(buf)), &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); + pkt_hdr_len = IP_TCP_HDR_SIZE; break; - /* Notify connection closing */ - case (TCP_FIN | TCP_ACK): - case (TCP_FIN | TCP_ACK | TCP_PUSH): - debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &tcp->rhost, &net_ip, - tcp_seq_num, tcp_ack_num, action); - fallthrough; default: pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(tcp, b); - b->ip.hdr.tcp_flags = action | TCP_PUSH | TCP_ACK; debug_cond(DEBUG_DEV_PKT, - "TCP Hdr:dft (%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &tcp->rhost, &net_ip, - tcp_seq_num, tcp_ack_num, action); + "TCP Hdr:%s (%pI4, %pI4, s=%u, a=%u)\n", + tcpflags_to_str(action, buf, sizeof(buf)), + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); + break; } pkt_len = pkt_hdr_len + payload_len; From patchwork Fri Aug 23 20:45:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1976260 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=vNBOzj5n; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WrBvB5ttpz1yfF for ; Sat, 24 Aug 2024 06:46:46 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8EC0C88B84; Fri, 23 Aug 2024 22:45:44 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b="vNBOzj5n"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 23C8C88C0B; Fri, 23 Aug 2024 22:45:40 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-VI1-obe.outbound.protection.outlook.com (mail-vi1eur02on2070f.outbound.protection.outlook.com [IPv6:2a01:111:f403:2607::70f]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4B0548895A for ; Fri, 23 Aug 2024 22:45:38 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=hhWGRZBP7OOHbmb2qZqOYjEu+8GwiMVXYNmEwXaT0Ay5G2BfXsXZnj04KOQFf2GsRTEarZlkZ8TFlTOKyo76NYP63BFZ5SMSzBWDTQ9PEzb1HE3i7km1IXLoYycbcSz5b6Qq1Kg6T9GT8hwKSdAPf0+dk5SFKU0vbnQM/xotrq2W0jhjMhfER7YC2B0ds0FK89VXOPLkV/PMyUExQk0QkV8rJA0z9IIo5buVA1QVg04QIO+EfVz+ytrLp/AJHLN6hdXdn5Nov4vgTEIKX2zSBwDCzfsY/Lr68aXSeGbEUT9WAKGWPV4bOo7SRfgtEG9fk5Lx7927WTsoqVbfoQotIg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=HLGv+pg5SORkHPEXuvhdPc0FAqiQkZHz4iUUkazxOuA=; b=Df5BG6roIhnguiNNBYKCutIMa6IYu6Hiuxt385gL4qJ7XggLDSG6zG/Nd9uByt81YoQHtu8Pu2gvNNlh+L0VMDmhNq5AAOdp4bx7QvDhj5KUt69vVq0lgA8OGzPxSI5SrpBsx2zb9VBuEWVVYlAmnhw7Mszz3StrW83y29uYttkA91HnuwOd4wOBvBjjq1tuWiGfDrGMqNHz363jYJ27nVAVOcXfHh1Fke2EfIuLTp0AbM847MuEWK0SV0mUdHBi6ZryHOc4xqKFt3Ca/Ei7fiRsNsWh6txexHdPV4VlGgHlTF2tq6ZxnpL5nGcLntDnk2yU5Dmvj2O55mtqAQH3Ng== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu; dkim=pass header.d=iopsys.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=HLGv+pg5SORkHPEXuvhdPc0FAqiQkZHz4iUUkazxOuA=; b=vNBOzj5nznSOTNP+lmMbGyIEW8AOTbPPuE588C7jorgXQYvXRUFftNuFQyohOwHEnTQvNcoi9QgSSxhkr0kZ8Vy+fzVQ+7o2+A649zHnnpNKGgSUTq0wJGGcOou7Zgi7G87z60H1dKioQ+DurKWDKB//GeVgrAnoEks8RmJu6mFaR1CZEg8d6Tmyv1C1dlLri4uFpjaJZj2tVrLXtn3NQedDAvGirfcW3/oDba2AJGe0PVsXJcpavyoR/X/RsH+a1rAITYzOPuc1UrqJkkKsLHzhZW4DOQ4b3Te7m8wkBkI3nPKYUMzDWk9O67w9KrdnEdzcOZg4N+1/WYwL5H8Nbg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=iopsys.eu; Received: from GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) by VI0PR08MB11224.eurprd08.prod.outlook.com (2603:10a6:800:251::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.12; Fri, 23 Aug 2024 20:45:37 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7897.010; Fri, 23 Aug 2024 20:45:37 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Yasuharu Shibata , u-boot@lists.denx.de Subject: [PATCH v4 8/9] net/tcp: define a fallback value for rcv_wnd size Date: Fri, 23 Aug 2024 23:45:17 +0300 Message-ID: <20240823204518.1010194-9-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> References: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR4P281CA0373.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f8::20) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB11224:EE_ X-MS-Office365-Filtering-Correlation-Id: bc51e85f-8c3b-452c-7b7e-08dcc3b48ad4 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|7416014|52116014|376014|1800799024|38350700014|921020; X-Microsoft-Antispam-Message-Info: mXWUcMSF1xyVFyKhzNWPOnAxLTaQ7U62/ORCBglROEEcm3EMjAHMUOjhY9Rp/Hdi2kMCfJ9fL2JVnJibAY0yoveW2F/rx0BiQWbFmInqUwPtBxBtO0ZTqD+G17rabO6swypxISQslcwOiuSNjrn20Y1lf/76R0wG/j8EvOfFzGk1HVgxrhBSNlU/mxJrvpUFCb9gf3AwFqxEsbvu1WI5qllb33HGFnHYfLR88Z0TqtjYpjIbpvUt3o1WLvBErKGgpkeMn1UEXtQoC1LN516J9dUQwh8dU4S2lXKmwVdnxQqo3pYIhJTEZPWP+89Ab7HzLLmvAgApOQ4nbtvuS2a7yOkIiwYhcH88g4ZnBjRqEolVIv/nZWYxhwgCGUqJYA49t5HufGwoC/64Jqo6X3QoNCKijEMv7RVogw2UP3lbbA95IxHvMFYC/n9u5En19qwUlihWV8RKn3UMTuxmiN+Aj4Dt+XE37cbPJKCxKnGZd3e3ey94Wf2h++18dZoFkn/W06DP9FZ9uYSClxvHqcOBgIV87pRqkPgul9okvM8YTxh65UnFnuHJI4Bz2H1m7RGZ2GQEsg5hvujltXpuQrL5/XXI5MVGh/kPpMwOnHc0c+hk2RKYMi/XRJ58jqFU1CtQU+L56LfZMCtjv8zuRi3OSXR91WrQuFcHb6By/5akzlpj7Oy5ucSlb93f70jxs5UX3i2+sDE0gJIRITwcIiA6vyXnm7mmtUD9RzoIoM47XXz4M7Pa7K7fw+1n8wQrmM5Za2z0xnNjIpYN989DPmK0A2V8FeQW3L0p3ksR/ZpWAzSLq3qyJK2t+zYYFj5ZqmTIE73ILqViPm2QAgkZ3g2/6aYtmxAG2bgj0YvQOFXAbHQ3Xe2gte1teVDY+cKExMYlBCpGu4kT6redpozuSebOMZI86qKLqRnJc2e7zSkhjqlemQV5pA7SIO5/2KNcdebIAiTpsamRju/9M7p3q9JnCyxZIOR+29I/XU/F1Yefhj8jc6juD0j9QlRqfLTQ+iiWyvUA3pRor3ZzF6rK8lXAMLdN+u/2oLyyXs4lsCfedbioQ0X010yxASr0rtFXNHHLkHCFLX66F7GzpGksM96EIYV0apw5ypFbbS4amsbTZSEL+pBZkBeRlmGfl5/pZV0xtRFBGzoduXcZom3mX4ec5Ed5zvY4/nE+tuAwQ1/gO6NVJ6oPdl/mIQFoAl+fURAzIu0jUY9Qc7h4nQRO8GdLw0uvx0kEHhBa+ewZviF4NX0hpy73ppZNSBE5f7Tpv0bpI/3ykRKpcKiGOYdMmv9x4sMGFathISjpmdV196cKyhVb7WBZ0Tpkq9WXpReozzo8IBpYFiLpFpszL9xAXy4w+Y3ChxViPIs/DDZHxKkamYrFU/s2VA4uDwwd7VStHa+evgbCVOGy0oC8zGyUVHBXq/G+l7wGodHc6VS6woQ9j0k= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(7416014)(52116014)(376014)(1800799024)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Cx8wUssgdu7LD+WGn59X9ZS+gBZuGCXeDVU3p7BtGNRmDQyiYRhCQUNtrh+zESQUVxk46Vu0A0ODmY+2O9A9zIU0wpvZtZgZ8z3aCvEq84ZZQ3hbT+hGbrPsZ/Yh/wBiqrdmqWrx5HWJ6h34goJgpC7fZNBciKoKJvP+JsjUQg4CFumWkLV6n641HbkMyR9E+uNQcEZZCMPhTfW6m/pDXK4hsGeFMZUACQoQEQdH9EDMzk/215IWOlQ9XdifMlPAJUlyMQ87WSte8NbrGPp/7fqzqIbcMsHJqkviLolL/JkWhC5/13gsPtzSnczdBiAwviYRd1SFpFxhXifaFQwUG2Sv3wg6+PYFsLktloq+LdEj7gYI/Gmw7/9lfE6qoaXrNSmw3NIX/Q4iBQEf83iTdUJeHFrN8udNlGssFx8x0StJEdztgKAAXSCFwVmZ4UE9fOVT+5bhY11Eo7i7XJ4eImwbvlzCpGUFkKbNbZ4tyAE50okCwDYjmhz9kbS3rcusucO6x4TxLptQTmStCTZZcNu9utL5TKmH++aUtu7Qhb/xwkf7NadI2/r/GKPksrHSF8XB9f1NLcuKlaKLJ07UpbK4Dj94lj5tVuL+iLV0OMju3SCdTCozYnH0wjM8vJVvXdwzVDiUl7NTPUICqapD9GHynXehKlJFt6QvF0uB3uHEkXh1bO1EK0PBg6adITpc6vZkf6NQk80eWDOJEx2ldP0NayF3y4f4+1N5WGqKZ5s2wIpGdL9mP8XEdmWNGhRhhfEfqve3YwHg9HF/IG1WOiqbYhfILAsZtuS5jDbFiM/YZD7j4R3D9NQPIIyEsLO7xO97xN+m7Sk8czflwhUFlblsIhR5oftZE4W6bHn4dtqhw7HLwYprJysnjUbE+gpIHwUs3uKTpbWJLeINM+BuWjLU42DbsNCB/Y7SlR5XAaxRIDPGgZW65shqnvt2K5eiJTxP6SJ7KWbh0gxB9+W6RMld9rW7gELN0NDq/+EAGyDc+9Lkw2iBU1VZtwwOMV5/Sko7MFgAjcJApkj1Rm5x9SEN33q5YuS49KXS5tYxqtbYVFF63+YeN+cKnYgiKONOWEdXD8mhRxo1/muH8y9G/q0nQFWzWjYZerGCFv8e7xXAcKSSMZkj0881yfQJN0h2n8Rlr7l3/Z/dJdgOeOhyxtk9X1fcwrem/wQE4T2rwCy40m4NML65li8ZukOV5wlZ9ZFRZNC/Br8p+GG4X7xlDrPJ8pcPl/hfvXEY/bo47V+Tx+gJcBW2YkQVMPXBhcs636uT44TgVHBLDvmZiYL2RQr87Td+PcQsKxxfJzBDgeznFKKHHkRIqZBpae8Z0jRzpgJHnNsAbonbWb93HArjsNSbe3fTb1DB3sVXWFZoatHqEkqPpbU/t0Z59yTInZUZCrCkEblFewHEhM611o8yupg5yLlxlOdeUyn7PZTDEK07mj79Z809xantFrD+oNh5VEWJHnIMDS5i7r/n9DhxR8jlLtay1sTJ/qr9KyIJFepDSHHK8PN9H+hfiK3utB6WDuyHmFHPD5nxRa6VQGD0zFV11j+mcItnBNlVP+F2T8tIUJhnDZaHIndWy0jekJQcONgPJIjdL0kcKMxgaKco3Frlu2CnLPo/o1Dbir3Ghhk= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: bc51e85f-8c3b-452c-7b7e-08dcc3b48ad4 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Aug 2024 20:45:37.2361 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8d891be1-7bce-4216-9a99-bee9de02ba58 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: yrkxDZeQUddH5Jldfgtic5hQJpfU/exCLJA13Eja632hceUcfi53ygWJ2214VKjZa3Se3HNYummEXfHRN/Qca/LlIL51fsd59ZCvQAIbJJQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB11224 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Some driver implements it's own network packet pool, so PKTBUFSRX is zero. This results in zero-size TCP receive window, so data transfer doesn't work. Avoid it by setting a reasonable fallback value. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- net/tcp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/tcp.c b/net/tcp.c index 7014d5b4f43..f0889d72d44 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -28,7 +28,11 @@ #define TCP_SEND_TIMEOUT 2000UL #define TCP_RX_INACTIVE_TIMEOUT 30000UL #define TCP_START_SEQ_INC 2153 /* just large prime number */ -#define TCP_RCV_WND_SIZE (PKTBUFSRX * TCP_MSS) +#if PKTBUFSRX != 0 + #define TCP_RCV_WND_SIZE (PKTBUFSRX * TCP_MSS) +#else + #define TCP_RCV_WND_SIZE (4 * TCP_MSS) +#endif #define TCP_PACKET_OK 0 #define TCP_PACKET_DROP 1 From patchwork Fri Aug 23 20:45:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1976262 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=q99vRZgN; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WrBvg0jwXz1yXY for ; Sat, 24 Aug 2024 06:47:11 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 66E9D88C08; Fri, 23 Aug 2024 22:45:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.b="q99vRZgN"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EAC6388B23; Fri, 23 Aug 2024 22:45:42 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-AM0-obe.outbound.protection.outlook.com (mail-am0eur02on20731.outbound.protection.outlook.com [IPv6:2a01:111:f403:2606::731]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C291488BEF for ; Fri, 23 Aug 2024 22:45:39 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=w2HYiBmkjPpgmIQRd9KjFA9L6B4eeGE/eUGU5Y8QOhdFVtt24ndnQ29GiHiQ79yJr4VcGce0iXi8QHOb6KIpCjjlnprSxLzRaZ2YRHIsCf4gNb2dPqzh1Lkx393WvEPoPZ9GfwcvAgnqLMOGtq3p/i2nE3YwWvG3NjQUilz5bbMWi1kfLROATJUsNcahUjYCqEMg4DtxLjTrBxxS+cemXWTmzwgRXys1ioBiIurQKX/zVliSaTz7WTiLYrPDvQFtIGnje++Rs/mKzvxGzvJuz58PKQaN90BUMR7s+3yNj2MHvfb4BLVy8Y/yqaojvww3YXwKolpeNkJMshYRAQMjvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=n0hnWHn+N8axKnxMVmTpRq/PkUgWqTf0fBcoWsa7eVo=; b=iN/rnCheEQdh4QVcTnW/oTHixkjbP4LDbfakBXm+ss3pP2ikJSwa0JiPzGJjUJkHAZJ3AwZnZaek2UDiNumt3FV/QuXkXTrh8jAIfS0l+FYbbBJ9/Ssq1cbYRKLI257nielQEe/+iMukJ940nv/239qxKcDMfqJen3aPpvMqUtDDA6Obm5GYg2Eb4B+OgnAhgBgxLfuLVdqQaCtfRwSrE7QoH7AQZjmH9vKvfkeR5gVqoo4RKGv2Tq6zUCLXE2uGRbqSkv6gdW7mVHjFc0m84yZgeMa+U4P1ZFCxYmoB0NEXTRl7L6RRlIoFJUo6CuvQc4EHOG4QVcYbd2jn7f710g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=genexis.eu; dmarc=pass action=none header.from=iopsys.eu; dkim=pass header.d=iopsys.eu; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iopsys.eu; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=n0hnWHn+N8axKnxMVmTpRq/PkUgWqTf0fBcoWsa7eVo=; b=q99vRZgNBoXuDwEVI6ajuKJEJkG4AtsFXxKq2h3tOURlV5gYx1lECbh9mmqkfd21a4hgZqhd7g525CJXAYHtEULKAeHHUVLJ+kCekG/zMHvcsgvZKSgi07dF99rXn5iTDVlWu+TaDvoVuwC5is3A5s6/bCfdN9qYX6H/wHSZEwN24lqts4k1h8nvLLE0wIkulqMXElUdkcppWgaw2qeExOGo3IQ8vDsV88XfvpZs/yZrHaOE9iXidOYc3xnnjAWJOlpFgPLgvw59vEDi7WICbpUEsEWtNZnG1O/TDgh2eJi49GmQNUwghpiGhccnRRqf7VxoUBsNcUWYSVGUqWE0fg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=iopsys.eu; Received: from GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) by VI0PR08MB11224.eurprd08.prod.outlook.com (2603:10a6:800:251::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7918.12; Fri, 23 Aug 2024 20:45:38 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7897.010; Fri, 23 Aug 2024 20:45:38 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Yasuharu Shibata , u-boot@lists.denx.de Subject: [PATCH v4 9/9] net/netcat: add netcat over tcp support Date: Fri, 23 Aug 2024 23:45:18 +0300 Message-ID: <20240823204518.1010194-10-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> References: <20240823204518.1010194-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR4P281CA0373.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:f8::20) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB11224:EE_ X-MS-Office365-Filtering-Correlation-Id: 5baa221d-e476-4f43-940c-08dcc3b48b9a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|7416014|52116014|376014|1800799024|38350700014|921020; X-Microsoft-Antispam-Message-Info: jNeWk97OXRzD8U06IF3ZeYdp2qULrirxZJOZohO2gCE99YqOZ+0ktsq5LBoETFxTSpfXflSSeJMIRdNR3wguvBDzYNASN44hggcfcvjdUuLu9L3iX4jPGebJkyPRI4w3nCDTLXi9pimO64OdxQ4HvT/vjj3El6U7gmfS5uhJYQ8TfQ0ol4NQ7c8fpXZkFtnkADWQ+pFBxgtT1Lb+D/f6YodbKROt+FeXXvMy6qmN73YU/0msifeD2aMdTjwketizLJZI9ukg6m9bynsRSemDk3EX73RvbutqgwMUy8leqi0DPIRatLABQFsoQyHrVf9MCwIJOTKYRz6oObMeMGNox3a26moxldozxF9QON1nGdSbfyRtMWz/1z0XGEDyA6dHHN3Fx4ykaKuqxiTfHgRSUFV5tSlRJG90SYgscFNShbMraTAi2IqbJjpu+3mWRXk4fyXSEcguMr66FhTET05O4FMmTQHKbPmX7omsA188irfO/RXBz8Fn89MPLTqVw9g4928NXRRs41+UkSuFw3Ifuw33krchU4eS1e6L0U6GGEwdjADiyMbAcNgWAc1bI0ijCQY2H8/ehKssU0RliAvvjWDPiq3u4gRBMg2dwg5mEIsaoDwsmgIEmmCKORN9JDx6Y97Ir5ugshlTrL3HX4ZWH4+jW17AMNfdam9a1gA3f3OAkT+380H1AOwGU29h3kT4KgV6Bk8oa9ih5CRbCEdBf3U72CJcADlXR/xYteSJDkHX0L3ENsHjaXJIWuYdLZF6XAl9NYTy2H6WhqzyS/5NfTGcvAfgBL56aJvz05CuMFru3F+i+LybBeKiATnBOWnnyS2sNWiAuqeW3XhYAf2xGMUafuGb8HoiL5crVpf50ulZUl3bzSItEOPpW1BMErmkR9E0TfJz4XQRP6a48Hk5zo+zvF793AkEqMwD3jlqu5XEMjWy90+V8MPa+bjeUrX9M9MrszafYLxQTrYGg9rI4DguHCUY142KByv5AQk4ImfsH7VnpeBBeaxTqZYO6d8OJkZoakUlye5RAIoa6tcal2TzYM7F/6LjxGgYaEkB5NncECBrWtADYNskWC23BJVww7t5+G01TWIvbZhB/zitHGf3i+gM0OfjHboVOiSaaZnHv8rRZOilK41WtyphwnBmAP8rEJfILVuNVX8+p7ye5pO319PWkzvbXb1l60TAABXyOQ3ZB95M68pboYiU+0u85v+Olj9br3Sx0xAPRr7CCWf27b33Q6xMQ1Zo/vZtH3oyFPhVRKM8KIybuGD6rZqJ7WdMINA8ybRW+JKyG6Nc7W0f/ABRS137P04rhjHDGGWp3zn2fzCTHS9Beo42FEG+0/U9jEbpJxbRDaBWA9sv6S6S5mKTvfE4fOEcSYA4zQcilTmbbtOQXJ4EEvKKqoq7ZnAPoc0vykUK+0q73eWXxLdxxRUi8cna+PRN+qrd5HM= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(7416014)(52116014)(376014)(1800799024)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 6Nvfq16XVzaCW4Zkk1RpkWMj0Qgpn/o5CeK807XqdBlPXjlg9VPICHe94i+mLECK64WhdMgRYdfFIa/Mdb8WkifIZ4jU5bv0oFDqdJ2p1yidM3WNkdII5L7sSYqqaEreTf0+v2XUMqIyjDHoKDqkanyE4sbjve/kX43FEbTb+0RuhQeNwhZm6wxlAKkTyPR+4yC3rZpY+vD1rCwP8PdHFNndTvWs6NSeU31HDk7EmyxAsHD9HPwgm53o3nMq1I5mr77+2DeP7RunXZaFhJBIiciFjjcVJVDFEAtVzIIbttSf9t6Xd23JpMkyBqAS7zGbrB619xk6xJ8nQ9B6og/o+C8/1GtlcoWnbjN9X62tTdxcFHNILp1ApubbFa1g00A4GQ1jJqR2G9z3JQbezf8UxNcGKAtkfCojMAtQ6DhX17FfyoeH07qtRfX1qs/r7SfwwDun6pH0J+8dcvtrO91gBAwZsLO/BtLOhhejBWfzZZ4ngFjN9yrApK7yMqJj6xE4ewkfEUcGSqH22Zs2PgmerPmPClB0cC4DcwLcnrmLxTGSeIRQVZw3N8lDhkgbGm6JxvjqWYjRzWSHJ0c8BtD1z9GZ1j0bijFK82j4Y84iC3BZzfTIp9Qh+6WeNjtVWSGO8+hINqZOuY3RRtw4WUZhzaJdordPTa5X6cYcqgLtvGz0kXV0UaowJYnqZGChQ3fcjQG9bAQhskVhi/B+M5m1fzKPQf/Yql+X4KSQyQwW1IsXbl4nBmaRyXFAcSU4LazLGuL3dvxeYZ6FjCAeCQ1Tveyd38/n5b7lf4DCl4EkS8uieNOZmnRxEu4TOkAUFCWoyo3T6YsviHbB3Qk9KpVzgvI2rp//FqszjyFDG5b/Q9ww3w1SW3YVjsrxGmH/pmZXgR85Q3w1+VOFn5GfCyaojL+iATQR4UVxgSAZ+WmwNS2R6L6P8gL/I7AwlFu1D2Mi/XSH/ipOtyR2CxfPPIfCEg0IMNkKmxLVGTboEL3+W9V/5vNNVwu5sG08SI1GuEZ6DQ8cCUswccDLbogWlJS0rvtV5B6cYUOLlAjK6jCXhadll++ijsJQxyjPddYud4w/Tbtrcv9B/kGW/eEOtIUVnSeTlHZiondQufp7xwgj+rfrFzy/aGydmCDQa1jMLqkw71LX5sUxiP5AA0laWm03nW9iZgAHncTRNgk4PfjpfCTuYqqGaUIeB2e7P4koOJtuL3PF6m5owt2KLbJ3CyvCfhiAQLyhKUca645O0tQkqcaPRwa8QLHL7tSM8Cf9cyKhqnP5+Pm3xuio3GJjTZ9pM65q5nUnediD7Xn1cYJq6wPZOLQQC8hH+1ltREjAQmCsZoODhtmliAbht0Pw4Gv3wWBaEKV3+CNDabX/smrbY+2uB34HmdXiussL4Z0GkR/AQo28aqkXJX1qyoQsyRzeMeMdxlR2dctxsX5b5j6TRpb3oIZYT2JHhQiXTVPZqvZzGnyUJExlZRMEeFZvs3X/1I91CcxN7sQQmRJgef2zq/Pe6l85WPqPAsIonhLJxcAE/oauZDRS7peapCx8UVxxqfw+h4yQweax2nhK60Uc7/00n6mbubevrkkM4eejDWiMT0h4GZ3wDgplHwpPmtXqGnMIpzvO6SllRn9JZoqsUOk= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 5baa221d-e476-4f43-940c-08dcc3b48b9a X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Aug 2024 20:45:38.4755 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8d891be1-7bce-4216-9a99-bee9de02ba58 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ZcjkurWGje0Tqg9MKqVSswFS77L77OikdKr7kv+4ECi4xwOVwWmCY2r2aFnVAKqDRK1C0Kjh2ftfZ0Dc2uRhk2dUbaF+5EHAc9bvfApFEAg= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB11224 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean This patch adds downloading/uploading of data with netcat. Client/server mode both supported. Signed-off-by: Mikhail Kshevetskiy --- cmd/Kconfig | 7 ++ cmd/net.c | 34 +++++++-- include/net.h | 2 +- include/net/netcat.h | 20 ++++++ net/Makefile | 1 + net/net.c | 9 +++ net/netcat.c | 159 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 include/net/netcat.h create mode 100644 net/netcat.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 978f44eda42..abcd003f7f1 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2007,6 +2007,13 @@ config CMD_WGET wget is a simple command to download kernel, or other files, from a http server over TCP. +config CMD_NETCAT + bool "netcat" + select PROT_TCP + help + netcat is a simple command to load/store kernel, or other files, + using netcat like manner over TCP. + config CMD_MII bool "mii" imply CMD_MDIO diff --git a/cmd/net.c b/cmd/net.c index 53ce2bc5d0c..6ac81415f8a 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -206,6 +206,28 @@ U_BOOT_CMD( ); #endif +#if defined(CONFIG_CMD_NETCAT) +static int do_netcat(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + if (argc < 2) + return 1; + + if (strcmp(argv[1], "load") == 0) + return netboot_common(NETCAT_LOAD, cmdtp, argc - 1, argv + 1); + else if (strcmp(argv[1], "store") == 0) + return netboot_common(NETCAT_STORE, cmdtp, argc - 1, argv + 1); + else + return 1; +} + +U_BOOT_CMD( + netcat, 5, 1, do_netcat, + "load/store data via tcp netcat utility", + "load [loadAddress] [[hostIPaddr:]port]\n" + "store Address Size [[hostIPaddr:]port]\n" +); +#endif + static void netboot_update_env(void) { char tmp[46]; @@ -323,16 +345,17 @@ static int parse_args(enum proto_t proto, int argc, char *const argv[]) switch (argc) { case 1: - if (IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT) + if ((IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT) || + (IS_ENABLED(CONFIG_CMD_NETCAT) && proto == NETCAT_STORE)) return 1; - /* refresh bootfile name from env */ copy_filename(net_boot_file_name, env_get("bootfile"), sizeof(net_boot_file_name)); break; case 2: - if (IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT) + if ((IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT) || + (IS_ENABLED(CONFIG_CMD_NETCAT) && proto == NETCAT_STORE)) return 1; /* * Only one arg - accept two forms: @@ -354,7 +377,8 @@ static int parse_args(enum proto_t proto, int argc, char *const argv[]) break; case 3: - if (IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT) { + if ((IS_ENABLED(CONFIG_CMD_TFTPPUT) && proto == TFTPPUT) || + (IS_ENABLED(CONFIG_CMD_NETCAT) && proto == NETCAT_STORE)) { if (parse_addr_size(argv)) return 1; } else { @@ -365,7 +389,7 @@ static int parse_args(enum proto_t proto, int argc, char *const argv[]) } break; -#ifdef CONFIG_CMD_TFTPPUT +#if defined(CONFIG_CMD_TFTPPUT) || defined(CONFIG_CMD_NETCAT) case 4: if (parse_addr_size(argv)) return 1; diff --git a/include/net.h b/include/net.h index b0ce13e0a9d..5ec826209f0 100644 --- a/include/net.h +++ b/include/net.h @@ -515,7 +515,7 @@ extern int net_restart_wrap; /* Tried all network devices */ enum proto_t { BOOTP, RARP, ARP, TFTPGET, DHCP, DHCP6, PING, PING6, DNS, NFS, CDP, NETCONS, SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT_UDP, FASTBOOT_TCP, - WOL, UDP, NCSI, WGET, RS + WOL, UDP, NCSI, WGET, NETCAT_LOAD, NETCAT_STORE, RS }; extern char net_boot_file_name[1024];/* Boot File name */ diff --git a/include/net/netcat.h b/include/net/netcat.h new file mode 100644 index 00000000000..09470e7f0ce --- /dev/null +++ b/include/net/netcat.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-2-Clause + * + * netcat include file + * Copyright (C) 2024 IOPSYS Software Solutions AB + * Author: Mikhail Kshevetskiy + */ +#ifndef __NET_NETCAT_TCP_H__ +#define __NET_NETCAT_TCP_H__ + +/** + * netcat_load_start() - begin netcat in loading mode + */ +void netcat_load_start(void); + +/** + * netcat_store_start() - begin netcat in data storing mode + */ +void netcat_store_start(void); + +#endif /* __NET_NETCAT_TCP_H__ */ diff --git a/net/Makefile b/net/Makefile index 64ab7ec740a..dac7b4859fb 100644 --- a/net/Makefile +++ b/net/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_CMD_WOL) += wol.o obj-$(CONFIG_PROT_UDP) += udp.o obj-$(CONFIG_PROT_TCP) += tcp.o obj-$(CONFIG_CMD_WGET) += wget.o +obj-$(CONFIG_CMD_NETCAT) += netcat.o # Disable this warning as it is triggered by: # sprintf(buf, index ? "foo%d" : "foo", index) diff --git a/net/net.c b/net/net.c index 86182cc504e..0e05a8f2336 100644 --- a/net/net.c +++ b/net/net.c @@ -108,6 +108,7 @@ #include #include #include +#include #include "arp.h" #include "bootp.h" #include "cdp.h" @@ -564,6 +565,14 @@ restart: wget_start(); break; #endif +#if defined(CONFIG_CMD_NETCAT) + case NETCAT_LOAD: + netcat_load_start(); + break; + case NETCAT_STORE: + netcat_store_start(); + break; +#endif #if defined(CONFIG_CMD_CDP) case CDP: cdp_start(); diff --git a/net/netcat.c b/net/netcat.c new file mode 100644 index 00000000000..ea225c68c87 --- /dev/null +++ b/net/netcat.c @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * netcat support driver + * Copyright (C) 2024 IOPSYS Software Solutions AB + * Author: Mikhail Kshevetskiy + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define HASHES_PER_LINE 65 + +static struct in_addr server_ip; +static u16 server_port; +static u16 local_port; +static int listen; +static int reading; +static unsigned int packets; +static enum net_loop_state netcat_loop_state; + +static void show_block_marker(void) +{ + if ((packets % 10) == 0) + putc('#'); + else if (((packets + 1) % (10 * HASHES_PER_LINE)) == 0) + puts("\n"); +} + +static void tcp_stream_on_closed(struct tcp_stream *tcp) +{ + if (tcp->status != TCP_ERR_OK) + netcat_loop_state = NETLOOP_FAIL; + + if (netcat_loop_state != NETLOOP_SUCCESS) + printf("\nnetcat: Transfer Fail, TCP status - %d\n", tcp->status); + else + printf("\nPackets %s %d, Transfer Successful\n", + reading ? "received" : "transmitted", packets); + net_set_state(netcat_loop_state); +} + +static void tcp_stream_on_rcv_nxt_update(struct tcp_stream *tcp, u32 rx_bytes) +{ + net_boot_file_size = rx_bytes; + show_block_marker(); +} + +static void tcp_stream_on_snd_una_update(struct tcp_stream *tcp, u32 tx_bytes) +{ + show_block_marker(); + if (tx_bytes == image_save_size) + tcp_stream_close(tcp); +} + +static void tcp_stream_on_established(struct tcp_stream *tcp) +{ + netcat_loop_state = NETLOOP_SUCCESS; +} + +static u32 tcp_stream_rx(struct tcp_stream *tcp, u32 rx_offs, void *buf, u32 len) +{ + void *ptr; + + packets++; + ptr = map_sysmem(image_load_addr + rx_offs, len); + memcpy(ptr, buf, len); + unmap_sysmem(ptr); + return len; +} + +static u32 tcp_stream_tx(struct tcp_stream *tcp, u32 tx_offs, void *buf, u32 maxlen) +{ + void *ptr; + + if (tx_offs + maxlen > image_save_size) + maxlen = image_save_size - tx_offs; + if (maxlen == 0) + return 0; + + packets++; + ptr = map_sysmem(image_save_addr + tx_offs, maxlen); + memcpy(buf, ptr, maxlen); + unmap_sysmem(ptr); + return maxlen; +} + +static int tcp_stream_on_create(struct tcp_stream *tcp) +{ + if (listen) { + if (tcp->lport != local_port) + return 0; + } else { + if ((tcp->rhost.s_addr != server_ip.s_addr) || + (tcp->rport != server_port)) + return 0; + } + + netcat_loop_state = NETLOOP_FAIL; + net_boot_file_size = 0; + packets = 0; + + tcp->on_closed = tcp_stream_on_closed; + tcp->on_established = tcp_stream_on_established; + if (reading) { + tcp->on_rcv_nxt_update = tcp_stream_on_rcv_nxt_update; + tcp->rx = tcp_stream_rx; + } else { + tcp->on_snd_una_update = tcp_stream_on_snd_una_update; + tcp->tx = tcp_stream_tx; + } + return 1; +} + +static void netcat_start(void) +{ + struct tcp_stream *tcp; + + memset(net_server_ethaddr, 0, 6); + tcp_stream_set_on_create_handler(tcp_stream_on_create); + + if (strchr(net_boot_file_name, ':') == NULL) { + listen = 1; + printf("Listening on port %s...\n", net_boot_file_name); + + local_port = dectoul(net_boot_file_name, NULL); + } else { + listen = 0; + printf("Connecting to %s...\n", net_boot_file_name); + + server_ip = string_to_ip(net_boot_file_name); + server_port = dectoul(strchr(net_boot_file_name, ':') + 1, NULL); + + tcp = tcp_stream_connect(server_ip, server_port); + if (tcp == NULL) { + printf("No free tcp streams\n"); + net_set_state(NETLOOP_FAIL); + return; + } + tcp_stream_put(tcp); + } +} + +void netcat_load_start(void) +{ + reading = 1; + return netcat_start(); +} + +void netcat_store_start(void) +{ + reading = 0; + return netcat_start(); +}