From patchwork Thu Jun 27 11:39:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953219 X-Patchwork-Delegate: pbrobinson@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=D12jjIYr; 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 4W8xSX3pTgz20Xg for ; Thu, 27 Jun 2024 21:39:56 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 32322885EE; Thu, 27 Jun 2024 13:39:54 +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="D12jjIYr"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id B7B768857C; Thu, 27 Jun 2024 13:39:52 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20700.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::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 D6BB188582 for ; Thu, 27 Jun 2024 13:39:50 +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=arcselector9901; d=microsoft.com; cv=none; b=VAloN97VfWjOthgc4oqVj+D1c3Oi1AKy6lS+3GVIWy9X4CYrrq4GmuT2kU40tYB/EByGXGi0J5R4zjte7YgWWbzYYri7e7VhR8fGjrhSsHJI8lue1ga1vmyga8CT8qdzuFvXHacn8D03zkA5gqoGYgdUXeW3pWz8IuNuevT4H/RzJoy4VW9JMICt45C0am1GPsvamjkvNR/IMLU9Fk6x8Lggnv3FXJmpzujtXXrWls4Jy7toG+IMQMpWGWrrX7MvsVCK6Yu7/7o+LBjdU2QmaxkDAdvXrEIbDyHsn8txITylzfEuyNpW/xoA/3RAQ2w2FT9QLch0xMF8zKJYDv3s9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=Mvub5FzaK6sCE2FEv6mUojRJwjkXtjo7lcQg4TvpKgc=; b=P8cbwX5T3L8dWVg+NVw9akeRQEB9catAYUnOJnEcT5aLqj5IE2cy+1S7A32pj1fvR6nkom3XCSfUl5pYgoojUlA6+qJImn3PAzYO60FBXShnsR89FSZ/mIQlhYi+yi7mi3i8RFVUsXRM2c6miI9XVFDfinNMJkHlQCvjcLjQtH9OddfrAtY18inImCnFZXWRa2LcFxSgY8BUEI+D1oGVSnj9MIPTDI2QImrodmJS8eWwb21uylAVQGe61xrCcdV83c8EIztpCDUvXKjJ5RswuctPOJyJxcTe/p/dr2OcwMc15psTk3X/Ew2wy09LBhNV+2pON3wpWZ3Xr7q/abjHQQ== 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=Mvub5FzaK6sCE2FEv6mUojRJwjkXtjo7lcQg4TvpKgc=; b=D12jjIYrOz4t0kgZBq1sj2MAjmbZfSuihoPKeYnL/IIOg+mFvSmpR8nqjM+6VsG+7jRgqr5mTBVP7aUP/18wZLUTLZbadE66RQEr8r9GLpMwwa2m/ZGOS3plzaL/Gq6q0vZ5CLAVUb8xHhNZFOb7rccakIWCg4Vpjp24JI1PZL+/YhLaWtHVyIJ1Na5zf+bIahm8JqmF/xOHFT+taBYpG8hKvd/6J5kPJTn38dqxftch64IGwEf+PxWMiC3zeCs8SpQMi6NRXcGn5sGixGAEXQG1TWxNNtKakgFOXZd2hErgZ44kRASmY/U0yPk//yhubYJfm5qis+jcvNprL0zfmw== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:39:47 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:39:47 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 01/12] net/tcp: fix TCP options processing Date: Thu, 27 Jun 2024 14:39:28 +0300 Message-ID: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: ad539576-9a69-4d8f-5aa7-08dc969dd8c2 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: AIRkWYvUCoEDdEcZ2OLA27ZllYRqsm+ZMVN+vTB5qZgmmsXOVnGdS75xMBYdtbsfl8iDaMoEAOaLrKehvLjep0LswSsfFg6F2oB+C6vL7QHrYlU2J3eDarJHNAe+e93oTZoPxA5bGVE2pUf5jis5LDj/be73RtI2PhVCzyZ/lstQYZlnldiTx6N10bT2eiWX3NIFYmt5ej2r6RUgfN8xiIkKt1yYh7pMGgkKEegcbgosAkbcn4iIe2qHpS9xNF87ORuA3yH3KS6+FY8CHtUY8sejQFZylrs2zgIxGdPqlkz6x78yU4qoA7eVPxY61MZKrUjZKGTIECZ+nF/hF2/i0RWy0ysvLQaDy0C03xn0cJ0tC+wFVc5jZILP4tmY5OOEmL4KuYDIF37x5cPFVwi+kk2UwTrmiNObHI5Y2ojqeZSqh9jY4G+HXpIkpLI9ltQNxDmpbi25rSRIi4zDRO5s6cjm07ueWentaYryuZ6sdz3iXmeFY4RRTrpbxcfis47uO2IA21BfZ/9l0zBq6ANF4xLU/pF6PUIuH9ZX6BuqVKSZWrBog4vX4PMIQqeob6p3dxvb5xN7isTLe7wqwSgMcVnHaw+t2Cz0P/sSCZHjzU35MRsy43FlwAJ5FIQoAwZQG12BLexr3xrsKVlFBGfPik9yNFaFS0BTC2V9EvO5FBsgOR4mM/A0f/dYAEcyP5CmoFwbo/dKDd1mfy/P6ulGUArddYSlv2ZQ7Vn2x4DHSerCwUbK4YYFLk0qcxUb7dHujSD4OlcK0HsukmFh3oR/O5sJJloWDnK4cF3zjFwU4URIqywirx3GdQDmyHGdb5RpxOvv2sdPJMbAhgfkw2zefBGRHS8ZQdFGoulMaGDv2PgO1shiOss83UzRjJlK3M1XAwF+O8FLs4Sq96niWALm+QG1You7mKk6fFss/mHIxT7ACOIOEjqfz6XOFJlAuOOAy63cEJbQ6OZcuxBOVrFKDFwE4QufcmGdhEXnNPF8IIqb2M5V35rpx9NjIk7je4Hjuiyv1U1I2W3fq+KncIQ29ktAn3wDeZWSQgfb0UHI9+9kKbqFA624jyRNJR6HHyD4Ka9tVeFbK+wJ2AP1jkxvj6+8bKhMdWt0VOHj8LGO1CLJiRYRovQZgGgygYYD4k+9SkQZbolX/jqAZJg1D9fFWgWftiLvYg0+Em7nt7Bzl0Lnipj95LFg6ODR+BTJOeuRrTjhPwkMwKJTXZw647pEQt8Uw6uZD3lhT5XcGgLFQQ0cIartNXrMfZHDggfQkHf7lyvN1NeEQdOT5mZ6wKee4s9OrM9+LUPc2MTXsIuptXFk/5MgbhELcpV1Zdb7pKp831pq7rVKbBX4QDuNrsZckMVOmPAZnsghIvDgGtqGWXXVufFBqwB6pqzB/O3KTNIu0Ej7J3Zv1GEl53vu6nGuEcs4MjGq+vPgd5Chr+U6W5Y= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: TRTjFhHaeLPA/iCpufWTWEU69vldl3Q1YyeNozYmjRw9H+auorw/zYHb+lWpzHPQRj8a02KEamGmfhpHiVuURm7/2lSZXF/1HzTOVeepgMIiYIlM6JrECANlu8Q/YfWSecdRheu2WyZ3udF8nheo0N3DJ60MGgTyaedj0hj3gSZXOgXaOMdRz4iRjEowJ13ZnLDaeXhjBg1vzfat3HxAswb3UgTvOvNi9dG1npfjp4cQfcPeP7shZdEtGR/Rv1TvnI+mxdH6XxLp7PKqEYEBIgH/S/EQIJ9D0L4TiRQUgJNYRQm9hYqMe/XKMlWkcVrfcpTrtUYdIMdSa/RspV0ue2obbijGWPQMZmsxrgXyK14tJkLqOVtinMzpB+l/HoJA5h5EjYgX0YyXnkSdv7VZDxGRgohLWvraMg3k1s0oyRAU7UjJTZ92iTPYm/6/kKiP09nlINi9IqzZhIFXR0cV1UGV9d9V93U1vk9AcMfAbYAMqJ7PHIgAfkB5EPljyQo1egx3QxUK9jmjl3jVS+V/LzpH7El85E6Ht02fVcEUbTDCULnzv2YPzOEUz72tq356v7gVPWi/EpCP5vo36SCx09+OS/sziAPG//5WMdcEDA3dbnvAvY+Hk5Y6BbSRBkrs3kXaWzlKI78YAlSjYiviV/jso+QPWYDiM9uFH0UJ5hliAdHvN6GRCj+gtkwcocFRDoUaGkRPlnugTcJmNEuWMlZqZePzHEvVKqRUEynDqUOW104X0+zpyrgZ3ZxVRIlNHZfEuQ3FvvrBeEZFPQEtlXgMY+EhG2PCm8SlR6Nqi37PK6zeI4jqZ/GR6cmmd7BXMaW1KBKanc35f1X/VjPywmWt09qVp+0v/gUc+9zCbHHQWsLpAUnIdbYheS+csok7jKEZfHSND5GoF3nbmzNd3ATY33vo4e+Aw1uQL5xCHfotkVFNVMg+bEKTFuOKQNqfbAALplfrg8D9jnQEhXK1B/DJPi1SJC4uEEj+TwzWV9btAmH1FQ7q2/RjNtxdQHUMgrryVvTD94Ww33hoH2NSPSddpwzTfs6wJbnikNQ3keVB12lGTuWYU3AWkcklD88WQ0S/ENy5JEk5nhaukAn0E4ZtpUgEY//E+iDM6oHU4vuNbgHrjTSz3Vl44OXrwG+29Ayyq2mqiTZhZfpaBDctJZEDZhaHQt+B8U2gMV9fbCDpEJQe1fO+WGzlj/XXn8X/KDDJBP59+EEZw02WFzF+6LXlI5UCcdtLoWhQ8Llzup9Qn6KG6kh3Pd8/izvMoxvLw2vahTRu6I6Fk73HnSK9LDBVjjYidT6jTGUvXRxdY8O1u0XOmYxtPCiQm1ojmXb4tDVQIBVDwWf7HnAWmZGRmCoxkhzySFSuVwok0itleuzGznNyFT408cII58KO2nQlcb68fbEavz72BVbN3NJuZJGfDOjxOdOP+oOFGAsuzDopSv+bW1ISPe+D0DUH9ej/GVt/8mW6FGOQjBkhkS5nUY/4PkXxvzGD1j4DSJ7sx4KssstNqEDVGuqebvVeek4thqAEQI29rXK8sQT3zGyuijQzsjwcM+s5nHPw4JZwecI9DAo4lmGksfGYrbGDEhlVJIpXsrR+CuZMJCaw3uz2Nl7ll6jEo9TmRjNJR46qyOQ= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: ad539576-9a69-4d8f-5aa7-08dc969dd8c2 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:39:47.1965 (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: ya4T6NdQFTcUJA5A/2POu+SktTrj5MOM64gKfjhNpVCTl9H9Hm9UaXG/o3dF9Qt0SZGfp2UVUHFUe24nC7usEU8FndQfWkOs8FTb9KoYWI0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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 --- net/tcp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/tcp.c b/net/tcp.c index a713e1dd609..c9bcd364ee3 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -476,7 +476,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 */ @@ -491,12 +491,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 Thu Jun 27 11:39:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953220 X-Patchwork-Delegate: pbrobinson@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=pa92WUdq; 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 4W8xSk6KGvz20X6 for ; Thu, 27 Jun 2024 21:40:06 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9066088582; Thu, 27 Jun 2024 13:39:56 +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="pa92WUdq"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id BE11D885CC; Thu, 27 Jun 2024 13:39:54 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20700.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::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 033CC885D4 for ; Thu, 27 Jun 2024 13:39:51 +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=arcselector9901; d=microsoft.com; cv=none; b=Cd4BQ7eSG5QWof0xnonzaLCNcfKhaGa51AZIZ6KXC9tG4QGOOx4WvUs2CGI0wNT28VSwGVuAp70B+IbGhMCtzrCQARpNUpYfRx4tJ8p802GHzJx1iromKUmWb00sua4YS5Wf3LHMSQlIv80MD72A/r5QoO1pF5rNe/6wkOIKhwHOyJgSv25u/X8PvKjtwDIKO6dtwHJa055NjwMNPdEkc6+ErzCd6kFB+6SzKFu0i0yDm9wRWj+6OzqhCxdr+Lw0iHnu79ZCMybsFIogFsCJNNKZcfjHAkdBWue+oQSwjO/uO7dyTxbuymAVHJx12lzM7B9xYfwLUkJJ0HwkCJfu2g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=E9mixrsFSVSkB8hOUJO2kKNC/w62S8gMTBZbl/yLX8g=; b=UOaJU+8ZpM4iPB3Lxi8BjDu48eHCPfm3Y1MLUr1fvsXvWSuJbgBVneJfJA825XCLe9PdRHzdaBlIfIIJ4PUpa1JQv413RNxdNI2QvMGxGD/gsttqWIFR+y+RnkvhaB2GR7VyzLWp+Kv57Gpc6Is60VB6OZxWRchjKIseI/KtW8ZPmJWgnfXZgfNs/SuWrJN90P85M9dusc1MYQtL8+nUZtOo8NRhz9mEKZz9smp3CH2ciEN2YhQcrvj72m+/+5rStD3Y8FlC9aM8YQljRmtQFtSI5H6aNVdrbFaRaLMC775dkRiTtHIsGbU1lLDAQgyKTAhmC7c5j3KJGrW0mLX7Cg== 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=E9mixrsFSVSkB8hOUJO2kKNC/w62S8gMTBZbl/yLX8g=; b=pa92WUdqnJalKKb2kLGK1aVndUhc55MsEyco+oGH2sQ5v6p72n2sfLwIhjkP27zJWHTQMChCX2EcRz214eH95Pnql2NyJCEEq10KKvSREe6wIx3wu4Vl/ab3U7vYcBOcoP7sutIM+B4FQ9bckSIYYocrDDHYT6p3ES1nYk98DWnSM4tX3lDcKr4hfGV56iUpt4sZ1FYeBlui+sfgrDdskh2uNk25FO2WVW1elpf1A3JBXBDn7y2IXjPrUpsc8HLEHYKsJPCgevXrjxQvuWumXhQpYTsay8GBL8LqItk05QFG02yk3PXHUlspfUEniBFXmS2pkXIFRq+8/zfVR8qqow== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:39:48 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:39:48 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 02/12] net/tcp: fix selective acknowledge Date: Thu, 27 Jun 2024 14:39:29 +0300 Message-ID: <20240627113939.100620-2-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: a984a6d9-60fe-4cfb-bf13-08dc969dd9b5 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: 215HJ+47MBv6S3Xhn0q4vGo5ck9hRTWwtFuLkwb+M2lB+Q7U324pzo4ad6uk+RhyKTokTq944/SxAoYVRodkWtbeeEZYlp9CQdpt1Vq9SiBsx6FyZriaxKczEe79BzfhlQhHrl+dQDwsX10Rm394Om/Pk+PkClLxJM17Y/YeV/rKHQmwqgyT8tuSoHlY79rlDcpHwl4BCoQyTRqJKTJqCtwZckgWSYz2OdWCWnHTnrj6iei8Vd3cD+YYxag9QLSI5UKX9wlxAcEikBaGU5hoGdKgOust/OIHoqq7TCK3YjpmK9EfBZwLJ5WUu8sqeFgBJB5Zpxgc68AhQq0wuLd3FKQjOCUXOfrHbasTVQBBrb6Ij77xUC4L4KVKM3zLwa/FiOrfVf3sYHJ9KDNxf0yWzjiAjT410do6hCPr4n7OEH//9OGaFReup3YwYBT0BfK4BL4pXpX4rGTJgmH9W9mnd0nTwYU0zVVbIzG/idUQfRMczeey5tzJeLmCox3Iikk4HLrZH9pGjiiA8Kl9Gj9PCdUKPtM+aFIbuYCRbx5y+hNN4ShP3qIgcFi8T3YiwJY0hJxAucq0ktqON9u/eiUgi1JDr/LIuKQt2Iz9cHEI1D6JcCEUkYKniYR8xYJALc4RdqO743j+sSxEFzuMy3ovAm2nlEhhjvSdv+50UdrG9TOdvRGpruY9ephydCh2zsylvYlt5TDWhMyOUxJu9zt3DGvgp3bbu61BrtLrXnqU1PK056QZE0VvfsGZgNXI6k55PWXtAMDp44jxcpAjrYpjdX4fhf7qaaexdrCYd4/v02Csx27paRTDcw2SUcxpTaEw1knLXlVcUnQz1h9qQW6Crk/rT0+TZDBwVHu4vDcfcDCpN87oiq90TeteDKrl9AAa6+8PwhvY15ZG/8RnYlUnb8w2FxEKXLlAjW9YHn4Ifb77Ymzxn+vDYjEsTTOzWDfhLm1B6vyzdxTrxMo7NuSVbS9UJjIFOG0v82oVv8JYlEug8SRBUWBoKl8q8zxm1/W2h8a23P3XcaSQC8UB2rk4dsC4XsBC3gWzupq8Am7L50QoEDEgHTZsD3JvwfRfr8m8LzxfNs7VlqzK9hAndUIeue82MO9ZcJkN/yJ8rC4qP7i4Eon1rfTNLZkvZzbkUMFhc0R1XbtgMbcgnLJ6AJKH5ouZAtBC4qMN1ijW3NuzBWz3xU9avP6vGULM7ZxrdhsKFkECaS8vy/LKb0Euz2OE4cF88N9EaHZqc+DqfxanZO0d12uyCNGD2FchCKcntH1EkbD6XuZHre9ojzjJrHiPK4KiLstWUklLjM2APoPVeC04ckhhtAmgffwzpWMtD5xxVf/gQbYboCdzxbEK1z7BPMwM52OTlcL19HkirPOpVf/t0NKoyCLfQdaWQDr7qcANENXB9iknBRN2mCU9UvxNQY8uiSJbV/0p86zKjBbTtU4= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 2S8avPMH3KD64K52DyYDeV2wGczzX/ZnqbEnvn7D5X2QKhDdL6tfhX+EfdXrS4W5cOGWpJc0qNh8oaE4ZTnszM8euEAQf8v6V6P2u9vPSu8yMBlSkfaiyBOwI6M4hQgctX6Agx8LYkqjAJAIWwzlqKbAteBOOZRvf6xnu58tmqr4Vvf+woiUofSPNSOUckg33L5vfoeLMXqfmdkgc9mZndOLDOyApy4N6/rML9wPQ4Qkn1bNpX9G099Bylj+DETDczXsvzlT9D9XFCXpWfUKvdBjp72HLA6QsEFR07YyuJkdwa+qcamGrda90dxXSFs/Q/TksDoWJK51Q4VGxjdapM8kpTs7KOAZLlW4uuDlbzLpgNZWXNTJn5MtHyflTKwBfo3XtoJE4x6ZcZnpkDvZIvMq6HRNZ6qWHpGuGtY48l+VC+PyzMF/xIco6jnQRW5vehc3Xvy6UigBKhkFVIt1AkAOUytGbdhkb/AJzR4aLuWAGXXyvlAbAUoluruehbSdg5rMtrHpGvw26knSgwkexEcQwpMLjEg9axcD5UH1okvD1jdmwNF959NnWGKNd9LeELVTIbGaLqzv0aylGAPL2F/96qcVSUjcjdpIfmdkFfgYxrwIb2g0i1Fr1H+JWCbFNpGS6e/Cy12n0nFWaCrl7LU0ui4q9kLLXMfP3MKkaQaDqKXOWfFQVWBy+YyiBwhzxobiwrVtrSy0iZnCgOicpL4S1aDaRAFWzXNqpljd6w4yuijqVmr/c2QwUGsJpN8RK3KDeX/Trazxv6FkfdGhCu0/Doy8FOGxqS+6BVBEhRjVHKVdDzKyFiOqVqRp7nmJkc6dtslEfvup49HYzbCt0Y4P48HneZTNfsfKnOg12humLTLUUwb2+wQZbR2rnMdWD++wNgvH9rPbwDEYaobryAavRRB0gDzZyncjHAzyzESkUAX8WxijDM9RIk8kFQkNeUMLEOVbNX+gs603olLeTW7s2OuuuEh0sUaQUpR5RkMTtf6gwQtntJsMwhdCi1VaEkRyyUFFnIvY5LXcvSzM6mE3VhfJtBTXXEEAhq2xYXlJ+CIJaB4xKXHtV/VKop7IfkIqHqfmWPrJU8+X1PwY72ZTODZ9cWyAFp2kC/mTUI7AgiRHSUJTh3Q2VHk/lttZykwaFNflmStw2dZ7SHTSqQxhriiR06t0mlC397H+3JxPooziYVMZ2/m9s2DAjCSYLMiRpgJNXUYrH7ImPbpPOsccebwF8ynDWqiAHaRXMnPT2RSaWRz2wJxu26WvnYkIxfy18W2DgaNtqPM5qA6KZ5PReiY2/rT2dqmVcVP2ScAXduWqvMFjRmmn3+ZkmhEBXPm+SYxpkydNbNrLd2KBjQ6r+3/+oiGkyM1bNYPK7DNIoCCG4IN2tSMpjViHW2bGMxn7X5bqrCc8zAv4IVso88N1M37T3mkB2cdqyEHnXUdvkCnf5sAKR4PwG8QtsDUG3bddsRv5wlfBwNcc/N3tVzkBljdJW7QifI4VgI4dafYo9Y/c59uefh5qZYrljKda9kpERD5L6iveY9t6S0iWQu+ZiHCPvpgIO6dDhvav6FSJHkG1/i6r19giM6BriOG0AStc1RbyQfzOCe3VGt353LfaiS4+jd+yY98nKCmpiWs= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: a984a6d9-60fe-4cfb-bf13-08dc969dd9b5 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:39:48.7970 (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: D8+EJq3CfvE7cEOkshZgnPFHKEh2Rq9fQApNRsBGM8lO2IOovrYdZkjqmqvT0AbFGLpOom21+Jub5ET/jbNzZc8FGPUlkoSoI/pe6PbyV6I= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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 --- net/tcp.c | 200 +++++++++++++++++++++++------------------------------- 1 file changed, 86 insertions(+), 114 deletions(-) diff --git a/net/tcp.c b/net/tcp.c index c9bcd364ee3..228e1e4872c 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -39,21 +39,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 @@ -70,6 +55,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 * @@ -268,6 +258,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; @@ -354,6 +345,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 @@ -361,106 +366,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 @@ -510,7 +488,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 @@ -537,6 +514,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; @@ -553,13 +531,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 Thu Jun 27 11:39:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953221 X-Patchwork-Delegate: pbrobinson@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=aOIJ1Qiw; 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 4W8xSx6TYLz20XB for ; Thu, 27 Jun 2024 21:40:17 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id F1216885D7; Thu, 27 Jun 2024 13:39:56 +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="aOIJ1Qiw"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0F17D885F4; Thu, 27 Jun 2024 13:39:55 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::701]) (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 1EAE5885DF for ; Thu, 27 Jun 2024 13:39:52 +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=arcselector9901; d=microsoft.com; cv=none; b=P7M0tl+7hN+9rWYBinbH9EPVTAy80ZxeSAPR4oVBxqErAAw6tipUzyGQ8arAtYo4EXyGqFjWYln0pnj/+94YgtlhdGp6POpx57YaoifHtNCqn1/WSrbLeZKVKDrSc8rlFtEl+TxbYyroC3IiG5kaYGcdGTM47oYawfJcuMIK6NTCYt40Q0VvjCBt+tjWehuKyiiLC8CuHjfGWmfFPWXFvdvfS+rgKLmEqokbEAMPr+2T/Netbe0mSpTN//geRDwHL/AN6E1vqNAQxsF3OiI6K1ak9kIcb7Q+jKCMkCVDcxcXEiezUaDp6mhRrVOok+aj4OY6IZn7G4RUiye7ZbIPuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=zVi1oJiTw/nBTiqVwS0NLxjth0b1g4/gSIAMWaN97AE=; b=ep0lpeLwJaEEWwozra2RXjzQsxeWVLfykMY6Mc4+MGHD2FUKDo05AY+o31518s8wYTUYC5qAsOVuvBQlXOBNWX6ObeyHWiCSGVkgwXPfwKKvkeW30j406RmFXDm5+8JDRF9Hu/5+zCOW58vPju4JwrdJBDfyql4GjwWO5ujzkoHxDZh9fAtFHa3v0NVyUqyDH3cgBsXcGP41OReZ/fEU0oJRXd6yEVCQEaRayYMF4VW2gN1TS3bururmuE8Nd7OCFASdtQfe+1f3Vt94PqxzSPbgq1ZwG41LhjddhuntVhf7CFiZ9kFOElM/6JZ6Xlj3dGWtupB0FWMcMzp5woNPSg== 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=zVi1oJiTw/nBTiqVwS0NLxjth0b1g4/gSIAMWaN97AE=; b=aOIJ1QiwZfOYLrqzVQJ5Wt5KLcHeIgkgnB6u0wTOHGWEf8gCAofv6Q7gp2WZ+3kko3jHh5d5KjKUO6kocWeGaq0emOC1h3/4qs4JZjc6WeSbuGVEsKSI/wdetuIzsYHv+i1qNf+N5N4Q7UNELIqSGc1gzOx98tR09U9j6NO9owj9Ifs+Ujx0g9FzTqGNnF533KHa+KoMcvwJmG67A4r3vk6Avslt8d6IowauwnB+ZClmkQR6A7+sybDcWW/1k7SjeaoTLKNUvc8pQdAUE6wt/E/uGjZEgOrT7pOzNYaGfBVHIVqd+FH07kTWYLAFIOT6KxV0apvLgt0ITGxdHaDBgw== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:39:50 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:39:50 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 03/12] net/tcp: preparing for multiple connections Date: Thu, 27 Jun 2024 14:39:30 +0300 Message-ID: <20240627113939.100620-3-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: 6dc0343c-a67a-4e20-3494-08dc969ddaaa X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: vxiocW5AfpzNwS3yemDgiSkjpEmeSYW9QOjqeVNdjjkEjZgk4L5YstWQHzu9aBdtOs3M1pCrT8oiEZzNndbF+H8d+piFJS5K9L6zy6rHPalDRdabZ8+BUcHFZ2pVnqacDfBDhTvdYWJUXORRzIVHy1I+sWDXxzA+kfHZyncNabevIEMsBrBLmifYHWFu7RCiYZCq4ATZC6T3zBC/0qOdW8rt+CfLNzTHPVd24L64+iVBtK5ZkxBgWv+99mB4tttmKzxFSQjFMjGbLSwQMC8CdrrmYFo71/+cbZAGX2jEWqbAL5txgy8qQh6/yK4bIdSVEN6LNydE8HV+OgdXvVBUBT5hrBW16k5jE5EN+f3G9NuxKlRmNBcvK9ygpFi84wF/GfOIFtOrS8+lNIemC2FCJstp0ZcO0UDK0PS+NJfliOHcAFHN8Gp7BCQagFPKzfXFJZnsM88y+j4jhnmlaHe8GUK1fyzZYk+B4tBAuiND7c+85LmX2ojpsUMlwbwSongW2exYrxhVxgLMR4ttjoSjZxN2z242JK/j0M3J1n78ovv1wUoQYZP11cGHYno9SsnDP1eU6P3muDtju1m+FHBImlCRSQODxodMQ6AIVw3rC+M9Fn0v2+2c0TxGiVzmnu1oCpNHb+ltWqP2v8i5fq8Mfl7m9zGmLcdCz1Gi6cu8+eR3lTbM3XTBH/KcZ+XlAq52g/XWtmGqdy0iWcu2YGYf45srh1r5DPpLmZuzUErkJtxYrZuSIKndYnetHSB7QcrZpOyBvwQIRdO5xAddF7iVMDRCPON/cxGQuchwux4/10Vx5xEsGuleWuzc3D7mEAbXqGFBIjRglfZO6qWbdiNKcMjZ/KyelT10Vii8ZI0wxfse0JbhKcvGxy1IVd6VsP6TXEN1x6Pyc9xjAYap7kCgbf1woDICEI/Z2pzm/LPqJ04CylKbLV8em5tuA+Xcl/zjsbKxiF9E/L4e0l9hBZO9UcGpFiVziR7l39efwPW9c1hleAKwaLTQ3cmwpP6kAYPBxLeysDj7H85KXbcnhdbWGuxH6O6fIuEZwSfnXnQljBk54HtJ1oxC4Mg+5Mh+0dvXQrGobtkyhN96TaE6LIWwKvOrUptRYsczT2yq0xrvKtmIJmu/tS3rmv3L3Je7POpcHEw3Ria5EYAiPhTxtxsOnN50mtRstKM8dtjlwbcEbaVS3HrP+8WEJY1eLefjzq+3Hl9Z8BPDphr6m1e+BVHmGRw3pXXWmwyq0jc8RG9m/m8eCcyU9YVT6b37V3TV1zAi2gVe3Cdb1EXnLZOrEO6SgDjxDEkQ+mTA2nIfUOZJcBxbv0eToELudV4jT0ENoPnqHUEz5r9PVLQDqMl+HfE1IQhgcapIi7yWrV6/nw5ZPeA1hDjCIDBFaKG2NrKHv3F7NjIVQ9rf6F4cBj21crR+FWFEHp+JX+rsGKRCrOIItt8= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: mYwuqg5NoWdB7LT1Y1zFDDgBZU2MEEUItHx+vysT1tmfgdMfL9ewF82t5S3V58G/4nHCTt/cSmTH/PJXtigodzNBq9msXnieYLlISYxNNNyRKLjdKV1wUX8fXY5bWDU9bjo7KfodNOIOVjDeFrBhsYk0avia6HFwAziDiN7yF3iO1L4S0Boz+3Q3GIfASC8DQQBPmklUGgJhcSNtYKBGxzXGQecfZE4Wxr/3cP+bjbmkRA3WQSozMFPQttjn6lqxPB31D+jW3qPpcw3iWo3efxuqZWw3lo7Al6Y0fEpOwLEfLFevciVr01bezArcs2zMG13RgnrkmbaBNeoL4A5YDpg68qIjG7UzN9fyPdZnWkOgpFxQkbugvKRN1S/ghZo2CLSGzs+XoUV8HLbiyvTWtJXKEOSpJBq1zEDTeVLtmO+wscNBY16r3q+QMrYSk5HG5aaVm63pG9NkAgu2h8vumBVCgMEgEoFCRFHm3/mQVMOi/5daKHA9HAjZPqJStzpaW3+AOuqIGZd8a8c3MdCllm1vqapmMhbDsGnEQo8/BcjeelzZg1EtCFDGJD215pDTTqnFgTOkcypP47hESXms4E3uKsgZ6c6Sm/Kbk4h2IMtcby7Y2XyiS7/v8YMMbnb5/AbiY7AdRVgZ9N7nVY7MI20KJVFD80KvEnVJqpzcRsdPNaTUtvKCT41/qzuwsSJ4W5CAiCh2ORhWZmNDEZhNBhGrmudWhJOMVkoZqMIaSaGRigcFGrHQBKN/0KLeqKgVBfTHkxI5JyMJtT9WjrT7CpnZTvSIobbKK35/Afsw773snvMkdoI2HtPrgx8Ch2mYSklNZRZGJ3wB8rwFr3MtZM3Ww0aJJKOFO67yTjZlw9CYlpf+4l7a9kW/Umohw6UPJWATcw04KysIpOrCQWC23NPpbz0LswzxjjuoaARv8QHsg8LHyOwspy52fZ4PHaa7uRUglLlFSgKfkOSbfYxV6rUR/rqbG0fsUUU8syk2NaJgyljGi7DMVGQ8RZkYDLS9gCIct5Cxd3ellae787dJQKUd5OKiIFbBTUXQ9bPkptBKxN7lCnI7T8YRmRWS1E489d4Z1fwHOXZVtR23Ks6Huc5qM1z09RRqqjWLJfuBRktzTz8Qd6yLvgt3dIbdioW1NyXdqr+5bT9fCbZcB2Dvh5KKeKnsDxX+qI1JFIn2U+msRYslj0w8eRY4jpi1dQNBGmp17McxFOVMtC0qq6ekFs9VkXPnLGd1ulSm9qHoTrn18Vc9Nwmq46xV0+k2H7H21PDoLpX1NxJWvsjpBnyYIS+4F+SP+Szb5qpRV3aGByd0Opsyuep1x/28qFZvmNkLT0iC2fjXSMXP3ToOTmag0ARaKgIfhnSBL6f9l+rnCLc/TcBdAM4m8A/ztQhtqod8GmgZM8gk/8Rq3sryMEIPviC7VyIyYSKFoDk1K27dcS8mmA2ivR8f3ZrY2wCO7cFGU9Q5MdqyQYn4bYy0xSimXk02ZD/zh6vZGnMXb8dSX6pkxVmKELYehdSZMnOel6IqfwyAoN307xMYGECAecHPcHxUCB0UNmciyKCdpyQKX1OoU0L6r6R9+P0YX+Oy7uZZ1pfD3g5ZhwQmOROU5KldXBDnVS9aRp/lAccel3UxqCM= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 6dc0343c-a67a-4e20-3494-08dc969ddaaa X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:39:50.3923 (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: dZlDaFbysQJGrMrZyBjf7wW0O/SVowHF4pHDtd97iDM50r+POlX1lBlcuAi6PaDyqaeu2pYT8Z0bwqTg0veiJAV/eA6WYsaGaWl192NkA3w= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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, just put connection specific data into a tcp_stream structure Signed-off-by: Mikhail Kshevetskiy --- 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 0fb2d250773..8f076fa18e3 100644 --- a/net/net.c +++ b/net/net.c @@ -416,7 +416,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(); @@ -917,6 +917,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); @@ -943,8 +946,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 228e1e4872c..80a161838f5 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -25,19 +25,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. @@ -49,9 +38,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; @@ -61,22 +47,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, @@ -139,29 +133,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 @@ -169,17 +164,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 + @@ -195,13 +190,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; @@ -220,14 +216,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; @@ -250,21 +247,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", @@ -277,20 +274,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", @@ -298,7 +295,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", @@ -309,9 +306,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); @@ -345,78 +342,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; } @@ -429,23 +427,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; @@ -468,7 +467,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; } @@ -480,7 +479,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; @@ -501,21 +501,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; } @@ -526,12 +526,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; @@ -542,15 +542,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; } @@ -568,7 +568,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; @@ -579,20 +579,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; @@ -616,6 +616,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, @@ -644,11 +645,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. @@ -658,7 +663,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++; @@ -679,7 +684,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 @@ -688,6 +693,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 abab371e58e..1c0f97a6cc0 100644 --- a/net/wget.c +++ b/net/wget.c @@ -357,7 +357,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 Thu Jun 27 11:39:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953223 X-Patchwork-Delegate: pbrobinson@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=tpjHwUya; 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 4W8xTZ3cc1z20XB for ; Thu, 27 Jun 2024 21:40:50 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5DA8688618; Thu, 27 Jun 2024 13:40:00 +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="tpjHwUya"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1B8AD885C8; Thu, 27 Jun 2024 13:39:57 +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.7 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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20700.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::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 D7EAC885E7 for ; Thu, 27 Jun 2024 13:39:53 +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=arcselector9901; d=microsoft.com; cv=none; b=kRaDV0dQEkPcdpbRTCnmfH50QhAT1P8pSn2vHGJ8QwBrdJo0bbF1fy63rnEejVGTNWWcsF15c8i4xE6OVGO/ILt3oGl4B5ZGsQ1185HWYY9h+HrL+oiYrhDoNapG/oiAhigZ72dEnEEZV3TSqlLycxQwfQwjpdAVDgtYZq59A18w+drZM24E0WKj7BqkWFxb8eql/fs37LsngI47ebfCsQolOv/WyHogOkOy1TkHjt/kkoCiBJzzQ1dIHSezLsnH9HmXZzWPTVGZJt7bLnimKyLxHZOmmAJ/epk5dcktvtmvsLutjaIHBbnx3izCT0RrupN8l5dClsiQxyFlSd5A/Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=CRfbP/erTypZTCTdyHm3rv9+XGGLQNwsZPvhwPREwCE=; b=Xum9tcrOtMQ4bqcFFlzPi0O6ppoZucpwIj3VJM2ZZRvQqE+wggeayR+FuZh+aMTQ8PmHXFk2toH3qW8j5kOnVeIXLbxpKj+sgZEJNcyfP7Ljtz5yUZ/EiJHmoo+IamTU+LG2U7EjrgPPwCy8gFH5QvBFKnYstKIfHS75ihWTFlR6X+mWdVz156o434dtMvX4Xyoqy4709Pr24HdFqPwOItP7Y0kHHWbQD9j6Hv3LVkQ0RiN7qe9fkXxJfLmtTf8JqaktDckWGUVwmAhayhZoKw0E4texlyKySDXDiuX8pZ8JPnKAfyLTt+ljvwOEGxu9ADMmxVoj3vrf42UnMQz3Nw== 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=CRfbP/erTypZTCTdyHm3rv9+XGGLQNwsZPvhwPREwCE=; b=tpjHwUyaa1teMvbaoB8b66e1KzJRRL9V6DpwpHjMPriL0wmDj2owBwdH3eCy43+L3LNmRpBY/yiWkbUXGIUMi+uYSImr1VjV0F6EvHZgL1eiZJfjIGEHNAiLbgcQoxCzzREW+7V2gpTp5GduQqDTTzS60TLq9c//v5uhh01bLyXJFgMVv56TlkPYK0EpYIjC4VB6araZdhUfykhE32CafvycCw8DGQDI1tC0DD46PnPlNPzWdZCwIjyoCd5KfgR83vBoNXzkmp8VwNPIjJnskOkyVDRj6QoejTSrJF+mmAOH9F2pvuEFIsXqj4b1KK8dnwLsy4/5XVKO1fG8wh0QyA== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:39:52 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:39:52 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 04/12] net/tcp: add connection info to tcp_stream structure Date: Thu, 27 Jun 2024 14:39:31 +0300 Message-ID: <20240627113939.100620-4-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: 5d5c0e32-82b8-46ad-d3f1-08dc969ddb9d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: 53eg/a3NwDKlbCLDV2ctp9NTjWO5fmg/6rlyCy63M+WuMnljZI5c+QYz28WICT1Gdl6a5MTTzUi++FMHENhA66VI3nSg2yccIog4qFDrld1tMV5YDhWS7NrAja4N+1LXKx8/IEtIgPRSs7jeDKfHAPZCDWqV3RBq6Y0DBXhTroJOfEde+lFigiRhWbmiHTZi45pzLDHtN/RC51CqWu1J25J2Q3hQ1kq4X/3KS0rtHLZU0/aq/fhuApoPweWMQI4JwPjVwpS0JJIH/ZwXX3jhbDpCX20Xef0bMjM58xhYZV7Akj7SoN++dg8YQjN1ggeB5v3OXTX/utxgcJFSSd3RsxVFMjiVDLaBF3A4q8Va1cP/kZJ88rcDW/lnzJZKxi9fZSWfQWN4w4I25KRFowkAB/N07vl84IkPj3YYufO7QAEvPCj6MZNq+Z4w8mxkQPIGaQnYv/7eUatyeh2eCJm6apk5RAvRnuH/JDTcb/kbrTpYf/B9CIFnh3yUbexYOVfYp6c+qFXonPaGyKPzcbaF+QxNu4aurKtobhiuo4TKhfPX+QPhDSRCNnSlblfpwIOj63/dEr/BHtKv0eLiTaDNpfhnp2bJD/grmlnDQ1i8+9+T/a6r3xQ7+2gRakeOcmc/tXLxlE4GKYt5cFLTvmmBbFIjM3olzckIWcPBhrokjK9/ruoXWHj0xqCpYyh4oNU3CNZyT7/6cnJzB9ryqVWQo4939JJmGvVxzsXoGruogevX+xSw2qhdUkocwrfXrwKkqtriqa87/oBydVJDHG818p1LPaXEY6u57zxclOmFp5S8Usdwb7IZ92NwQxrq3Hlp7rlJ1JlUpK7zhTJsgoFDhN2LFgj+mF9QzmYe+XF9xmyX2b3rp6MYqQYJHqxIF817jmu1Gdo2qA53Qd86Qw5MVjkjw63k/LPPj8Q5cJBICS8mlvVSG2etWxqM6PX09v61DEg9k9KVx0MXrAai07UDr8GbcJiY+DcjqwjNB2d+23VpC/mpTSvCIGN2iHoAi6rdot5PHA3CcJWKicCqZo3Mch/YYNdQInkd871JJYMoKPRF2Sy/8plVadj1bbP017MNHCq2wR8PAnNgkcbYhixNIaQo23AFRvO4PzHYbr25w3P/TSmA+EhkCqTaEpkZzE48I8i1ygAKm9o7uBl7oKU++Co9UMEvD1YWGHNGel1eRPDN6qhnKD1h+4qjJMqYVe6CqD7eMXGNviimZhcjo0O0FFWIWHv+5nrbh90mWyreqK9kSZz+7LA+0udKEN69HVOQooKhdbdlBF473spzjdVeIJk677Yt8dW+LNHa3tW0cSHLJVy/s5Rn1O4JFWWi3nBcNkX498/ujVh5EZmp7cmVQ++v4kb++X//F27M5Ix2poBiLxejJ6mETzX3RtnmdaGu9SO3DwusxFzWUMykCCjjn6WRv3G8/Y4e3YEKuHsKT3o= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: gsp4ZcIDLC/umyG9oDRbc4KRqJP6eSOOEYH/ExArUv/IK6VUPDT8Zmb3vmOCEjoZClrb3EAAALLVuv9rVBz52niyQTypSl4Cb6MzxeXK94mrcTBalKG9KVNpIA0yMFcY86G2TwnHiUBUBgiq4iruha9VP8GzlrGWAztGRafl6k9hXvIHQKb44Mhx87xtX+yAWYI9Gh7YHrzYKisrJUrWcyQacYT9OG2p82svoiD5EwKt6Meww8k8xtVHDJfrsdB8gXIyAKhA9zmq/T56NFu19xLhJiAQfV9iduAZbNoLTILt+giH7/vv4JR2EnHGa0EekQQoNVtKScj7W8SFJux/2o35iGanrRxNn4Y5sJhfwFZtxVbmVD+NYBLCu/GUOtfD6ZSKW/TrZxn1qJOuLdQhgHtid7qjG9EN/kplE34h/Npbacw4culyXjLq2aC0zaW3PJdZnYsMtQ43axlLzbmlr55puUCaf7pnQG06QpkRilLXD7e5ci88j00WsECqxb2JZ1H4cOZsMreWwbhNK2koZZSY6A4/lmaBp4Nnkpa8k5pTahT0dna5o7wV6G0tBOtiR47HUnh6LjCU3gwWwUk1g13v8vccM1ydstSJYX5oCPGReAnMi2Pl80zNy7/3eVIxFTX7yv6U+AFu/B7vsnAMLTMv7bZxWIa8XpAetsvJcuopNQhV4zpKRcj922UCbtX6xGu2D+DgX2rS8tb5PBfuz8KOdEBh4YowYgxgQZHRcEHD1vGegq3CLx0e7YCWriy+KCPUu1FNdjJqNB195sjorptyamMgSBDalT8JZ5BhKvPvt7jO2HtDOTIvR17aT5ZOOqdjbfC8CoP3Xn77XDD5u5wAdWlhFNwWKVJO6KbBV1sMTWfu083aJ88wRZbzuY4R22rsLOSpkKjvQ9hQ6OugqXnP8UHOn26e5nm06hY4yrFGbhbxt+UwobYpPNzf28Hg8XBRDFeHKhdqEE/IB2Lq3tF3XAlYDpNsnf3k3Rr4UUlezK1W7qBGPxc8FkKka9Qs32jJnkEEXdzYIXL/aLgPZwJfFS2AUfw2FebDyzT4sW9NbgfL9uVpYZqpJn8NHTCfBdAY8EBRjbmfOlYtF+H9IO7qXpECEYxYgAgypNWihfgUUL0rEi838IqUthaok6XXtgwKV2QTi36fd8PmC+jrfuLPsIrGlr1wXA/33UasIE4Jhog7aV0Wo0niTuCMIrCHTVberKMSwdv2Vp+2OKeCIsknHSWbpbDkp6j4A0eu2QKDJQ3lAimq2LKrMrr8xeue5O6tfyF/hWXYFCKL4LogslAkhn+VoO32lLVKLFxYQNNXXn8r5UuFJZ2skmZITeVGGcFJdSSJuxUyrE4j3wM+FrkBLYns/oHAN55w23OgSm9Dt3cNPX7w8Ah8JUmro9wAoDB9BPqhJdRxlGhJJez03u9HWJM0zl/P03+G7a759QzkCBJDypx4x1ogUthygO/Uq7sLGIG5wekP/5j6E2BtjoFmoOAIF+WGu65aLN4hZzWF5CDcZ4ZtiSkP2xHykql3Ivs4qddgKVUiI9SOh4YAKf5Enp93Fao/wfWsLhA15Yf5pEjdeqFFGcVAXQhONh3Wk1mqmriSVeN+DuTeIM6N01Rsy0OWiiEZYftBRuRbTDw= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 5d5c0e32-82b8-46ad-d3f1-08dc969ddb9d X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:39:51.9912 (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: KISkMBnSegWNamryssxZ4XuFNz+rSE6rbzu8rs5QB7aPToNXTCfcJzrmmjVAhbg7lDUdhqTc0Yc58SEZr6XOESW+enTqisH20DHphvxbYZw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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 --- 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 ac511eab103..fe645245f0f 100644 --- a/include/net.h +++ b/include/net.h @@ -668,6 +668,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 @@ -676,8 +677,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 2eb52ea2567..de1048e366e 100644 --- a/net/fastboot_tcp.c +++ b/net/fastboot_tcp.c @@ -9,14 +9,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; @@ -26,34 +26,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(); @@ -64,12 +67,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) { @@ -78,8 +80,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; @@ -90,17 +90,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; } @@ -112,12 +112,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); } @@ -130,17 +130,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 8f076fa18e3..ff3018e6494 100644 --- a/net/net.c +++ b/net/net.c @@ -416,7 +416,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(); @@ -901,10 +901,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); } @@ -946,12 +946,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 80a161838f5..efa12c9e8d3 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -27,6 +27,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. @@ -41,40 +42,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) { @@ -223,8 +279,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; @@ -244,7 +299,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); @@ -265,13 +320,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; @@ -280,7 +335,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 */ @@ -291,7 +346,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: @@ -299,7 +354,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); } @@ -309,8 +364,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); /* @@ -333,10 +388,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; @@ -617,19 +672,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; } @@ -641,11 +703,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; @@ -677,9 +742,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, @@ -690,9 +755,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 1c0f97a6cc0..327fe3cfbce 100644 --- a/net/wget.c +++ b/net/wget.c @@ -28,9 +28,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; @@ -138,22 +137,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() + @@ -168,14 +164,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; } @@ -340,10 +336,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) @@ -352,13 +346,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++; @@ -442,26 +434,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); @@ -514,8 +493,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 @@ -524,6 +501,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 Thu Jun 27 11:39:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953222 X-Patchwork-Delegate: pbrobinson@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=cE15/gwy; 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 4W8xTG6sSJz20XB for ; Thu, 27 Jun 2024 21:40:34 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id F3B95885EB; Thu, 27 Jun 2024 13:39:59 +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="cE15/gwy"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F13C6885E4; Thu, 27 Jun 2024 13:39:56 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20700.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::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 DF26E885CC for ; Thu, 27 Jun 2024 13:39:54 +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=arcselector9901; d=microsoft.com; cv=none; b=GdmwHCdnv/qbznSi89u1DMEFPCG+BDJqBMOk3ljU95HaxhOJIUS5Bzb7S0g159v6Tmt1NPDc2030NtwfHJzJvmWaYT4TNYinn3iEKj/tDH9s0AYeQa9Nx/djUUjrUKiuF+yfv4OVPwAy/8LYaUX3O2YZqrprrFZMut1ILFdGdf9zGeGwPTYynv9xXfIv8kkY/5f4KIb1nOZeciQTaduxuJvUcj/QK+xYL2AXeXn1V4sjrZu5um5SR8HCKqdEbariKYKvTeqiP5r7IyD6OQKmPhPYDm3nqxXdKRn6BN/i9LYlinmlka2Kwm6joBkgxjPvZmTu2ittJv2kcm71HyXDhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=asRGgHwwsKyhCAK379dkHSEB5KmXCq0/XVkvSNT1vfk=; b=KdVbq6CTWBJxwfgnkFJG3hKPVOPYC87VRs13mCw2VK3Rbwx+KCNQ9wRFW6F9LleSGVeeyiTL68fpyQoU1vc9YLcomV6ocQukaZsUqeIrufdwAg2Tgt432QdsNjbY85VIUOmjEGnTxWLDVAd1dn9hF719buM9/edfzmmXzkQRPtKNC/D45LQzfSWDlxq6ngJD+NtZdKKLpfLRyNE6zjtH4Qod/hWMdcTPFNzn5RuKeHbg8oMytCXJKyM/IOLHGJbtOPs63KylYJkUX9fWTpmn3+pfXcixa0uG3aF2mcOCR6iNhokksXYOAWoeIi2ai6zBXABI76+N5X/gAuoXnJ9EfQ== 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=asRGgHwwsKyhCAK379dkHSEB5KmXCq0/XVkvSNT1vfk=; b=cE15/gwyysYqpttLBJPVDC45IPzD1M4K5iwgQr46DzxY1TfVJDhhDGN8bXsraubX7gjM7Kp1ixBGj0bUAzx9q9LVUP55IXscm5DdY7sYuxtlwutHi26GiI6rK+8f+euiFYlElz6bF8CAxL43Kl5u4lq4Ar3j3UOPcC4F2DeWpcRvZpSeiZuVP9QJJe74ZmV+62oXrLTPe6okL+hGwu+uMZ2W09oOoWoYT1E+23De0kn8FAwwz7di4hQZNCIMHJGNTZcasSVTjDHyRf2Rbtq1lNfTQVqYtvR8HoCKPvgIpKkFeomv5cMR7owgvyRAzf/wz624WcfUAIFx8bYXsp1eoA== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:39:53 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:39:53 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 05/12] net/tcp: rename ack_edge and seq_init to more common rcv_nxt and irs Date: Thu, 27 Jun 2024 14:39:32 +0300 Message-ID: <20240627113939.100620-5-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: 7b0bd18e-21d4-413c-a271-08dc969ddc8e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: Ei7m+FD0ovZVlOPijqsA1Hk2TjO9faFRMR1/JL0NuUN6WqP/rdQSljtkydV0xlzKrYfWsh05eVacxhPmXsU9R31Z9A88iYRXMjK1g/mbhhsfAxZNtWkPc7J3ESSjcoGW0kvkBQP8dMD3aLyVEFlSknMNJm9A62K/+WEliuzxi3yOWTsMmGmPMLlbR/Vv/N0BIoZco3JNdDZD1+RLmVoFZeHOua7debIFx862rzUV0frebw6pLlBqp5j+a9xCVarhclfdAYykpbc/Zv3hbg2zyHRN0MRKNKO5oEtX2a0QoKWD5kvTA7pjDv6Le693R1dkmg18AUz1pxUkUCfc1hvYGBUe9VfxD3TYRl5FTKJ1eLh8EkKeth6wPPPp470C7Vc7pYOkHewTzaASqe38v+pOV4U8ab+hDWlVX4TNWUJCie/NlWQ+fPoDOJwr5MFZsT4khpAvac7rxCr16ANaU09l1DFcHxgcPhJtu6PWBZBFSo/UeDVC/W8g7W3GsomRUScl46LLs+27xruD9QjYqiz+MWlfj243kkm2I8ps69OFL3K4iJ3LRBS0klVMlWkKbEVF6hzQxkj37QkzuAdttlLHJBAQzK5qbD/tDQrs71CHbOQBLPeht+I5z7oPZqeZASi0+16ZfklmUtB/TXlbWa2AIRqIHSiMmIzff0wvNCPHB+durPQjb4796AXscS2CqPQBK6tudKDLFbYVMYLt9qjh5gzsjB2HaZU3Nil170X9lmLUlDunjbLaDo08F85w0RkP9Mth5KTv0WEn0HBmc4rcWZM7k/8ma6mZ5Rd7upcXZQclv+DziYHS1M+0s6eeS+OvDre3nAv2kPmS88zeglq2OBb12QaRHviyh4M16bOJ02CH5UW1ximI8neoD9cZ4Yd+A6Db8amJXX8nSQ/r0CMWs0YzUwYDn8oylesrFr/Vt6szHXkJxl6JiAWMDMnrKh7aTTHp5jeBmSLgiOhDMYbkSAiFJesFH2bXkItDyi4o3PVHHGV88/iFDarQI5ktPDxGCjEqFYxg1LXc1TKw0QaN9j8KysG/NhoJggizw1MlH96Q1B2+V65+BHm/gLjtrEaj80enB2cLwLNfeSHDoTDoVO3R55ub0iE4HgDVaA0VXajr5fgiKhRzyAqKKVLu44FSoresg/hq1Rfo/D18Tj2WeQAw7Ty11NzKY3E3W6ccqQUnFQRxqTIzS/wvTYXFp0dnZ5F0S2KVevWn3iarRmm3lkkjn22K+LpPM/Sm6NWAkKb3+MMk+pCbjshAdxpHnm4sISMnvulGiPZwTxfy+nz++IFXzucY4QlkZZpgWDscQ/T+IDqKTjBDEMd/0+BgO2LYFNdaoK8SrA77oUrSyHP+wK05PctWeYJo8xCQcdX4Az4Es9eSTOip+ssPD1n50JvZnIG/sSh2d+p1G7fh/4uGdHTbztnBTZCGYJHvr68Gvww= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 92xTV0+XwhXCStrrojdOZ6FGq5+XVMFEoF7dEe0CT3EMAAQWsTqYs9MlZXk8t5H9qvshm5HWEbhZKbi0ifW6lJiPyuyk1iKkRIs7W9R4WanYdjfe3CwsPvaVV/3LcskBb1g9OzzaPrsYI0tPY4CqHMmz1DO45zTLiA2NPi2UOcamLSv4f5+Dj/aXCqRgbGVrw9BSBUW7reZ/xOoJKSu7HalWgPWVzoByfrChHMZiFcM/jOyshCIOfYNeblWZS2d1FytN8oQCseFKbvMS8JNvt26w2PHJJGDV8d4w9LQeAb8wKiib1yJOcZYL0rXZSdNnG9CZpDKHvkrSp3J2Nyw+GfcZy7a+rGYuRWMJrsyCPn8rW7pkq07PjFY9k7+5mj1PXbkdTYb84ITUQ46UKbhhakxwveUxX7ODibE5ExHwAeu/nC79o7CWVwtINUe9J99WzNszhuVSB+qrfLP6pye6B08N/mKFeIWQuqqqd26GRiW0DYGO3J+7RuB8hLjzntsoFgmIjXZIthiIkWfjdsXuBKs5sSmgWxU+vNs6UOfN9nCxe0F7ld/wB6fLfh7KNYQdXZvPt7LldROZQBv7Wm5qvK6adJk8+d7KgyhlIHD3w2ZixEDGoj4G5YO/FxpJ1rnZqD9DHjZRiwOEKHDs1RCxcjMI27Ko249pc3Fe5nVeqOZLb2ZkZPovnOJvk5S31WKocDoBJ7yg2RJ3v/nVG8AekKIxOHa/HaE6AZ8KhtdUR9pOJiSVvde00/PPkkXMvvNCACtLkXR+3cPnqeYsS8eALAgVj/RHgTkxqkF9hoeCEwGSAJhLM84j8Y5oIdkh4TAlmgz31IVaTOq0iA7FK7/aksrLTfJSuIKE6IICLFlqEmyc05nwb4sX7qjRtrEwqF+3vLTjpVag3EZ87IYA6stf5SfePtKvBL6OZkElpsVgZNDA18oXzcOXjsPEr7RmPaEFFinbpJksAwzwgoVVwV3xOQ58Z9ZMTW+/LK6Q/hShh6NctLND4LbeJu+jHFKFu5NxrMK/19DVQcixNZkRs4H2WW3zIQ074Kjm9yjstOwWa9HFwQ3OB0McS90QWXa6zBkFcf528jiDMBMaNXbFs73v+Pgxdvdx2fENoOgEhYJ0bfWLQagz4ddo9+k5PjbSyHHGsPdkWK8xku97354DZLEmzVUKKi/2c7Zp0fNoRc7vvI20vdSoTiw3FIFWgZIs9xcBoX+gFNKEkvZRoZv0Hkc2VFHgRh0R4K9K2IuIKQLCZP7+/3EFjA4lC3pvW1csBeiqTqNjL6fHJQr8eGkpkubtJ68MnxLUBvygNxTyzIih+upi6lhSiolpLqq0jTNNVvoZ2McxSV9boHh9Trk8IzvoRYy1lxnEgxMy/ARr8e6t4VEHB5FLinKIgDnn2mtWNV2VOs3oTi7ZPZuo0kEBvAi7j0lr17idKN+TrxXfNqQjGH3s7KwlkVPnOU7tTMA27i9a/M/DevQhqAkaGMlAK+5r3W6vYys7+jZMbcTZc8lLXndM8A1nVhAQTdzR0oQP05peFND4wQn8CDDTL1chtf8FgpAcz9onTTTIeie00a6J7o4E9GKVJsm3lwEyyU7QJY6+wlwYOFUyeIHg/YqJQpN9uXNRog/kBG1P+Nms3bFdVNY= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 7b0bd18e-21d4-413c-a271-08dc969ddc8e X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:39:53.5583 (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: 0W5c6Ay6bpGPPWr60uZM4tQ9ZcREb2V2mFNa8Rf17gtDYNdG4t5QaEjJh2qad09invQKSlBVoBwPytCK8SnCW+7CkHFZpFUyc+YUUvmqR5w= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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 --- 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 efa12c9e8d3..2a0dcc4e771 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -361,9 +361,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); @@ -397,10 +397,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)); @@ -435,7 +435,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; } @@ -464,12 +464,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; } @@ -490,7 +490,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); }; /** @@ -567,8 +567,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) { @@ -584,8 +584,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) @@ -634,7 +634,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; } @@ -749,7 +749,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 @@ -757,7 +757,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 Thu Jun 27 11:39:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953224 X-Patchwork-Delegate: pbrobinson@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=ZN8F9Ta7; 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 4W8xTh6fFWz20XB for ; Thu, 27 Jun 2024 21:40:56 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 268C3885F7; Thu, 27 Jun 2024 13:40:04 +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="ZN8F9Ta7"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 36579885FE; Thu, 27 Jun 2024 13:40:02 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20700.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::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 CF85788606 for ; Thu, 27 Jun 2024 13:39:57 +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=arcselector9901; d=microsoft.com; cv=none; b=JiytwhMx0bGGxswl4d75OGALHByzTRyiuM6vwoEiYPa1rUK16OB349EDKemdsyLMAdDf1jnwecj9lw68GdFHObOLrouwcNlxezXSNojcWNKE3ImMRexySC/pYXnyIgJ96VSxXroVY5Do5faUdGKD3hV+Q+JtQ/HX4sDE2KnBvPhZ0omofk9G0NZlDStHIYEFRg0h/2qWt0T1lqzUGBfun1rGVoBaV7u26KNF5fjdA0F5F6Sz6IR1uh3UCy15me2Dog+7+5eftCJnMu2CzhBBX7GggZcJGYhAJEmIlbKw7A9yS/9nrd0AbvHWPb5e4NpdJCI5c3EImYUvUcP4TZ4FZg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=FMLyRhjr/au38at4tMoWFWNpsUoj5XC9/x9WS3a1G2s=; b=Z3iQRrsnKIN5HBlmwfAOHOqIWQtPs9I3RLcwCT0ljT5UqZhk8+aMaWl0epPk93bLQB4g4KdiOtaEvLEPgitqjyc1mxdcY63jpquxS0xSrPAieo9mmnIhUhItzKPgMKJeo2DVrD4avBuS1A1aQSbOgEtF76Zmb02S/7zaXF/wXaGegNXGORC13A5tawmbaoj8KZUMpcTyCma3ecOPm3aJ+yVCXkqy2ikMgc+JiMxnyCuxnOURCAd6CLdkaE2Cmmdom1Zz1XaRopnZEom3EH7/qbzwDPz90CY34C8gnBsVgyrumxZgYlqgIVeDmYDzSJWnC/VBDKYazmI8bRwcvJkX4Q== 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=FMLyRhjr/au38at4tMoWFWNpsUoj5XC9/x9WS3a1G2s=; b=ZN8F9Ta7wtyIfHi1w3HBWWsIxemp0e+yx4L5D0XVLhFYPee2S0NLibffSs5Bvpc0F9N58Qc7W1QSEP3LjAbj2JIIBqkZkDE0Q96IpqCYQh8yFppm4KRGojPrvsXC5I8ljgCnis4YhxSQ7pUYd309dCtqZI7NNn8u//0UpiWuRTVldLIkYD8YVdvIA5yGKVB8zjdFo4xutu/2lx6IePRRMU7qjW/oGaWAQeS9lODT3tknWC2yqrFkjo9qSrZ1x7FJZwCw5s+ZqHXA3fIXyL+Dq/B0VoRtO+WdALKn2+l7tV2Isj+Jsha6TNbRXCCT5PBXxfwKsllGK3IuOZ8lcEvkJA== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:39:55 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:39:55 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 06/12] net/tcp: improve tcp framework, use better state machine Date: Thu, 27 Jun 2024 14:39:33 +0300 Message-ID: <20240627113939.100620-6-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: 75d2f33b-4295-4871-fa83-08dc969ddda9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: vrxSyLx+PItN3k5/1Pf0GSaTCIaY7nhPN03tHIN5RxvUp18L/68CaRZhhmdSVPx8Iu8Fnj1rdS+RROxDdlLdWT0q5Hwy5JnfEcJpb4FheQo6XvDwlQkQAcFq3y0HRINmAWmQe6yWiQd9u4Dx6eh+/Tz/6pXwHrS+tgWsYmlyOV6SjryoQqowhrZBFWPzZdqznkgVSqn80NSYvIvKZQ4a3oZ99IhztuZXiXhopP7phSZjfbj/0i/QF016CNQ6fFNEm6wDbFgP8edx33nrkeH3s3POQAn6dcmABr5J3Sm0P3B5W9WJx45Oio72LoBfyYPRQcAt0ywa/Lf56JEnU9jLDzL9s+GtkiUGSpqlfAOLp8h/KpCVzmJwDeoWD7tswgMKDoIb6WRDhXwhBjvbA4i6yjEvgrubSZvgUanMpMc6fyEa6lP6kkoq/xMzleAhR+iAUXSSWLw4Qm5/ZiO1AR/Qw0LhOyjb7gkTAQj0ZRuuLpx8CJRPgbgovrdSNMjTuA8tVZ3TVdyUTNFKnlGD+Uhuq+cVhOalh8hiCCreznkdJT7G2GkEj0EH7VlyzUHdtlR3+w/eEF2kWOsN0+yM81tloDr9QFWkjNDPEX8FKKyyKhbUCqRMo5KLO4qmoDI/MqsubIwgaQtWN21y3sqc58DwqS9kJUtQLyENN/ajVwS0xDpqAb4CqrmuqHHdQBvc0vANMkHmRQKcxXe/EHT2NQEoC9dHbtBCm31K61qUN2FCCoomDZv8goQvK9kEFb8KMr5fAl6xbMoXbF4j4JCgX4PY4ttIfqZpgl6HOZeWpX9y6iI4fS6opg97gfjPJAfU8ZLhMx1+9dtcsanWDNdg0S5XT+oFb6Ppaj6HEwOxmIlTjouQln4UTiNreInuy/G01OExvt0qkq/BetqMA+5bo/TDn6kyU3RsaWYRr1HBpqimI+u6CcEZjREVwgX6F3lCDoFdNdDVHGhQ6If+k+h6OtDWEB48ZkIvNYN2TTaoJkT6+ARL7qD36+y0F5JgaYLDiy97mXiPeZ8zfPzNBbGHLxtWrA5cFzTsWYCK1D7vPgJygAosMSDrruN79jFzhsImouzy+gQ/cJ4map9rTY+XmLv6LcJEeYivvTHzg0LVvAZoOBhy+Qo8DvnQrlT1KIBOlOkLQgZsxLL2Is3BLCoxqITftg29YgzFtQsxpyH3pmwC5vqmiuo46Nrp2OiGf4+BH2U6NaA5ooq2PHl2QIJITyIiLOoxvLtpjncRsB6inWpVGMfYXe9uXVgebyeugE6B0f26mRVhx4Z/yiYbW920ldimCEryumdrcpUTs0nGfkfHstmIDt/fhFPHAnsk5/vwcaTda9EMKngbPWbjzlL7FglHgT8WNZtbfsCLwp9+IaoEK8tL1F68YJP18N1Qz/8eK8spQLWR/jBUP0bYAKfXUHt0NUvtwpM+jJm4MX5MOYlU+90= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: s+SjDzZfu5WB0k3QakHrtpzy5Pi3qOdGNVYu5NWkQGZ4/T4beAdB8EHoHvuu8SyY5mKMmePed/Hc6gPB89QbqOuidp/wP6E2Ab30l9LMTU1YDaNNQT0uBGRIM6RJ4wEwPgokzU5pJTLH109Tgooi6aI2VW/Cu+zuJWpJlhEb/cIEBXOioJfkzOtp4PcTOaSiY0C2C3rbhsVgl4BL+svy9JzNoCzboZn9AmSn+fUKDd6B5eF8jiNZAt9hauoALRFvnGa2gyDnmVZ15iPhgeyREvE9E2ygc5+0gKqelqWS9y4rmcDtNCjDFqLcPQUzG+0xUhnDur66U+m7vWG+t0odSR+2jLP8Iu05YeFdgPaVyDqGtyxdRbFr/aOrO1T/wftMqP9pVex2MleYS+RtagUL2ZVsI37w6pM9llPe1yMSihYqgAT3/W2INBMuKOBUN0x1DC7zG8VdC4NFijtyMIlHA+wIWpjJMQKttuNsmGe/mVxJghjvqJ30/wCqJubQaTsQxidqps/Lcsiq6aQW5oOZ4UpPwyE0oiFSOCxCJVPEOK6zApLPfh0pjWtOS+ArFRtZqpfvKcIiTr86u31FG5ydPxLuG9OhR2SUINFGj+zwLdKgvnM4LQDdzIgVaBh3kIzWrKSYsx3QcxL4+nsp5ZARDTXrYYSgN/18CF+6zqDdc3/hQ9EPW3YhKzEGi49E2XOL+DKktFM75E0XUPq0SaAUe86V2/HslZR2Sn7YM9aZI1eh1jiqggF1jUuxlSzHnunOQwrC9qosOstRWNaEpQp2zGevpp65qQHad6o7I/dr/edDjziRFcCz7XQrH2mnJgkV0k/EeduoG/rRHw22tXIwWf1E7rLNzcukDSi5nMzEAlxgbSX5+U215v+/iThLwVOqzv+0eGUafcD2HwF4EWkIUH2/k9XzQpDypfilNdWr5ewWpUV0+6oauPFVXaAmrxBGmwF1WFdvyLUUtowHV5Lb2ghzNmwuTjQMKoGy3MRToyCx2b70k17Bt6r21h9mElUNhfhFl9SafpxDg+kwWgo8b2XBqhRBRt94WYKdhj2PddQpiSS+VAq4frYiQHmPUas/CQm9pDnXDjfLUj3GmE44PXB6FPYwhrCkiyRnYhm2gyX5nF3mywnp5QcpvYKdDpBbeRqH8UzTmn6VmaK6rI+G215mJMB112uJLuYXjnf/lUYB3GatGd3b/EpL3M1lyvmm7QE4YuNhVNoJmRdDJKVm3yT6OdgGDAQjBw/JoceOD4PsNhmi3/qYmOKrMkH08nWm0KSZx0peA1i4bMQklWclwUlgnbVXIGbR1HAusD4A2RVi/GCuJWzjRNv71ouKphgvDfBrqovWqQpOrXtbCnmdNThkVnRf/vdzmdj8gy7N3qdkbzvZYu+zgA1QchKPfn82RCvoHSiisharrfhgrGP5/l+/wUeahq+MD8ou4k8Mmm1BHQgLYSlQ9Z834zIBe2rr+SHw7OAFWjsiC/2W+cojgdeTDkHofdVtS80w0IBgBKq43W9pWazkzQ5Xn6ioRtBtbRxGbuGkS9d+K85D5wPctVgOsee9V1D1vTPdJn6GDZr4rxfCdEnuorhVppzhTlFWnngf3zzE4H4/mInvoxhiFzMreibBKlFkQUu9eTblsx8= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 75d2f33b-4295-4871-fa83-08dc969ddda9 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:39:55.4618 (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: Z0ikvtmQC/WesTyeTTw2NipFLuuKSA6j76ZAS5MFts/c4PT1t7tObzUeR6MdoeLG1djcV0MoyyVqYrf+APhgEiHCsgWEDGrRQUu086zSCVc= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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. * 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 de1048e366e..30eacca8d1e 100644 --- a/net/fastboot_tcp.c +++ b/net/fastboot_tcp.c @@ -11,140 +11,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 ff3018e6494..0fca11d3e8c 100644 --- a/net/net.c +++ b/net/net.c @@ -648,6 +648,9 @@ restart: * errors that may have happened. */ eth_rx(); +#if defined(CONFIG_PROT_TCP) + tcp_streams_poll(); +#endif /* * Abort if ctrl-c was pressed. @@ -954,6 +957,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 2a0dcc4e771..a5689a892b2 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -25,9 +25,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. @@ -36,12 +45,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 @@ -63,6 +70,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 @@ -85,15 +107,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, @@ -101,15 +178,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; } @@ -123,30 +199,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); } /** @@ -301,18 +550,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: @@ -329,21 +568,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, @@ -383,7 +617,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; @@ -502,6 +736,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; /* @@ -516,10 +751,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; @@ -534,129 +772,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; } /** @@ -668,9 +1107,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; @@ -714,54 +1150,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 327fe3cfbce..c91ca0bbc90 100644 --- a/net/wget.c +++ b/net/wget.c @@ -22,48 +22,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; /** @@ -96,7 +74,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)) { @@ -116,330 +93,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) { @@ -487,12 +284,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 @@ -501,14 +292,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 Thu Jun 27 11:39:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953225 X-Patchwork-Delegate: pbrobinson@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=YyPNfWHH; 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 4W8xTx1dsbz20XB for ; Thu, 27 Jun 2024 21:41:09 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9B7AF88610; Thu, 27 Jun 2024 13:40:04 +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="YyPNfWHH"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 20CEF885FE; Thu, 27 Jun 2024 13:40:03 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::701]) (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 A89078860D for ; Thu, 27 Jun 2024 13:39:58 +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=arcselector9901; d=microsoft.com; cv=none; b=klSO6ctFyXzlsRQiJUJlIBl+QV5Mi1vQrYydmRrujnu5CseMQ6SkF7oiGBXSfVP8fOQ2vbQOZoge5kbeBa/rvWiZEvR+tHKoC1zGhHkwOr4O7ChLd44BVZu/r/z60yrkcd0qJSGKpx9mZcX38zuqukenHY0iLHlDeD5rCIUHTptXEKmGAnnaoIbW3+O/70d9Wio75nZcCoxZea8NXBDgzQhTtqocavuw+FoKC6E3UcPSqT/MDSy3fJcQRoMo19LApiwri437W7VKxM7JyO6N1EfhrUVSYaIvFBV5T6m+crhYLmIZq1y7hqp+jm7vIujutIKbgQq0RlR9f1AHSR93hg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=GN/n5Vl7RXfy5892P98nnf0B5IhQIrsi312dauzg8bw=; b=hC9RUEvD1XGdKsbME7BmGLGq3Ud0KGXoh0yBgr18YmQiqDk4MUyf4Q1cM8CPJF+M7uWDg0CVSX7EkPS6/7w2Hl1TXxhofj+a6calT3foXwM093pOXnLUoRZwKNysdDZi7Ciqz+d1/Z640qX3fEekGSSbssAGcU5xsHUg0ilXrg2rGV3Tn2VXWP2DrYHf0jLMlPTZuoElDOwXxcvRYRKh7qgBvc+JCCxOPERv9gw3Yq0iFgEt+j+SxGMZb4UOPbVn6JiQ00ckDzQNXSK2Sc9GzFFjEmn6UAxZJ7IzXf71xhYL1ZN565TBULUCbM+zPFczUz/wvojMaIHlhik7dds6Tg== 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=GN/n5Vl7RXfy5892P98nnf0B5IhQIrsi312dauzg8bw=; b=YyPNfWHH75tD7dkO1iwa5pFEPNV2rU2KHSHATT+99fJ0EkNnRcVO2vSgYzR/DIQMm/6kc+ITKR0Q3bRUhRRqL/yoqNJJ2vUN0L666t+2UYU/+Nx/vAhuwIB2JbWsf/rCik4+7aVX6Lup9K3BYrJk1FnHxD4eJ8ozX3h1IAn6RASvQVbUoQtdVyUv1sPnSaPc43FgfnposNFMg3cbsVZwoYfiZ6OAPxSf9masnfmkZcFIh3S+gloO/MUOYAWKzqwbLZIJ6yaSqzdRnY7QQhQM44UG3UMwjnSEJayu8S/jZCNdHC20Yw23VLYKqAwVGQdu+nhWQBxgkAe+Ema05PBIKg== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:39:57 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:39:57 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 07/12] net/netcat: add netcat over tcp support Date: Thu, 27 Jun 2024 14:39:34 +0300 Message-ID: <20240627113939.100620-7-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: 435644d9-ba44-4857-5f50-08dc969ddea4 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: J1xYnw3kcX5JX0sMP95uGkDRnNSdq9BS1NQsCkVxGJ08DqQZSQWM09RvHLjzw2l1FyIDOzNP7blxXuHFx+yG9UIAMbMh6Pd7XKmP/RcGmrtm/yrmq3tExY96KSZjBWXDnuL6yzQhl9JYui9HU3DuaCUqC7zQC1a8SvyM2Gq0oiijemqGbwu99DjS9XFaKpy+TyVD8xsgnO/eNeEyhatib+fRz7Kinj4KMrA/2yNpMQyGDPJLJf4+8vViRJ7LstF1YwTEZNRdEUKbrURc4FxcrO55EzaWqQbf7M/9X2CvSxjYc6D/lrxZz+DYCTjLDc7hBgSffFSZFdB2+uJdSuqvlpTu4OYhcR0odajhRjcGW8yHdZIAy5JFeEGfd5Fab7f8vWsCnD7DiGcFo2bY2vBJ9jOo30/aDsqtKWMrWaD6uLd/MiRm0Mvy3Im57bp/X1wzlW+Z5mTK/ZXO7WURVnlShVvhjLL2MhgDSkz/xgdN7JH4ZD/sXqaWu2zAEj4hX9Q22jXfvkUjXojCcfddIZOakOlLB6hky4SK+Z/Ncsgkp4agAjVrw4m3UvrYrE96S01XEUGu2Is7TQ3GY2/g1yrVe0YYFAJ7H34vKxq2L24KhiU0iuvUJvlbtLZdBFntaoO7qLymo3rMmASqLctXaE8AJPJVqaMQmAkOxbZ9jDECXtOyV1q7OViGYgYFZSTKBHFbAdyMz4yPaLnKLTgqaaJo5yMImcEeLYP2IepxklezO2z0ktbrqa+rUpFcHIQPnWiN90FJlsaViFN954ji7NXzCy96gqGv2QWf3sZQDKtHJzxEg+HEsNth9CSdCwjjwiHiZnKH6eYxsA9kMv5xqBLwBdQfgW/9uPWaWOPMFt6VX+ZmR/cczBLoVZCWBFshjXqN1jsqlWVJ3+UvrZeIdxhesVql2EBJ4orbNfB/0PB3ztbYTsNAn92jygRVLjCGoTMjEj23RORpugXWw5F+rT9Q1oXMXEKND7JZns/n/EhL3yMjv+gzw5yK3TAzfW/6rn89k7Jpu1+N8u0EKmw3RIepQHJHuXxSla2YcZd9Qoh8mqbAp3C/gGRsOE5jn6kMeNaKrvkyUZgExOlkF4faIo9+n/xIF1jy/T2nQKYlfiBBWQSTOwSQuSxygXhIuPMbbxMbWNLR249UVaFxlrymannJPFizvsuKI80QYqYqZoN0MXbs5VKPgVaZ3khWY5xPJcNjoZZz62QJBUoCPTnWtUItlE/fKxW1XqoeKYqNlhrh9tYpeIPDMGZ10s139Zta3JXfAOvoRvwCPYxY/C7eBdIcrHszzeKy4DXdbHj/ZqbJcDJSSa9rUVIlHK70eBvyPy8m5hc4n7ehXZlY1P/ZoSD2xp8I+iW6RsXwqfRF+g2fMPcuUNO/9uWSooseXyN3/UfV0cpG4P+AKSfDNuLZgBv4SFHb6jrxnCv6JNjmhyLAQUA= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: ORNx/W74RcbgM4gXG/HM1SgB8uZhrJvkgxRHOSlz53T34Q0S58VChDLJ/y7Mj2fFLJlhB1M7liIHqs45Vb+X1YD8AREbEc6VTwsr822pvsfouRCahtVmXS8m6DIRzb6U24k0ZUSzfyv6Hn8qxJbgOGrUDB6qexIWusLc/6VAdIZXUynSL6oM/z2WwAF5KT2fSPCbAmeYtunkgehQ2UYy53cLFtVWMBLLLWfUClj09jqHQ6Kk1O3SutdrjgViJnVbBmpQZIjnNG0Pl0nZ2m1DrxGF6N46vRIZFb3ePGi7Gex9NedFpm8y7FZWj7gElucl2g0ErKkq0VzFocUbkgkTjgyRUg6Zr9wMLoPots3ISuujo7qTpehcN8s/872l5kVSH1GSqiG2usIZJ0p7bXw39Pz5bs50Ah4cW+gH/C5i9+oJY9CVy/hrbMN8SFrcsWtVXtLwXVIxtf5myrPtG5QrQ5LK9LmDs3N4qGhoWYCPTKDuTTusk58bSzZBjTnQ6vy8IeO8zYpGRnELD9fJzzyBtVHftn+rSigAzp0hdqTtqVsLyFKK69zRtgtTaQodm4qDQtCyPGXUIcdkKPK99amBi4SbuNw4m9aoYNfIFI1pVwUHj3Fn/Ym2LKh8mvmMsCKiA94d6AKEeSMhc5JBXySn2nr1YDbmQWgkxmRUISdCiadAq/ZUWc/H3oPBiNQJUXqF8/Iz0A7+OJDEVwSRNPp7Hq3azhpkhlN5udpVcdQZw6F6ec7aUPUlR5eaZVJbiczwo3077lEW9C1ZVftKHwtsNfjtnKM+0qDM5jxzzLAn9ACV8GjM+AmX4BNmlzbVwo+yzE2r1XQIOGmY7n64g7mIoVgE8aInJB468/HbcjiRyJS0I9fnwXmzhT0VBfrUF8JBN+EJBqs6WGvwK6m8kCDYyZh5/CzOVnYH1G3Nb0lFMAA76rCKjkyk/5Zg1Vbo8hG062DN3EeHwB3efmkf286jbGQ8JwEjULWDbTkiwvGnPyBkWKOrpJc6i+BivgIb0tNIvWtOtsxi92+uEIAd+Z4r5JnGLOx+8oZ9dJapti8jFoOAegLaNcc454SPDbTX/NOOqotrOEHAqIOuexKjLryAK2OgXVR/l1t1cjs2Tk1if7nakl3dfVX/5xPPuf9S+O/31CjzRm9xZzuTyOhMuke7yhlzMIqemi/WND3lR6+SaJhenGoDviD0nTIAbzD1tTyvKJW1HMLQJMdV0QGUhaxJAo8gvCBXoxpQckX4DfSd1iKQ1bJUke9iuhabgXtUpTwiK+Az+8xNfuYl5vK4bPIQGFFMBAMRXlAGH0/Mi1GmilFHPxA17m6KPf/aqgW1oINo0uK/cOnmbDozAS5KPSGgvIE5cdP61NAimGbmjFmOSd+T1vopZ3NE0P96Ove8Bdj60NqMoz9Jta0uRiKs8TLAL8afxunytcuS1ltf9lxgkmtPIXwfU5xK/xkvc65VGQCfrk+CLz6Y1fJqtNy5tZafNfGcaFdYpO/HTLdsl+Vm8l12cBVsG3YtHFiqtKkkkcP67HUPUHlh3qBwmZJm+KBK94IZP88YsmMuNtuGDz+z1757PolmoEPomvblxVwvFBhpZNIsPg9B89wArdD13K5w8c7KpCCLJ8zp2jEdUKs3X6g= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 435644d9-ba44-4857-5f50-08dc969ddea4 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:39:57.0648 (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: iBKfyOTSM0VmgXvM/afTQuwQNckCkOSei1qPd3Jl6qbzCTyb8v1iGniaEQnyrxrssoKm950SUEYFGQ356UXeOIlbVMhMLn/mg4Xi9ELOA+w= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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 6834bbd82f3..00cc13e2006 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1990,6 +1990,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 d407d8320a3..ecc1b49f52f 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -208,6 +208,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]; @@ -325,16 +347,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: @@ -356,7 +379,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 { @@ -367,7 +391,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 fe645245f0f..235396a171b 100644 --- a/include/net.h +++ b/include/net.h @@ -516,7 +516,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 0fca11d3e8c..809fe5c4792 100644 --- a/net/net.c +++ b/net/net.c @@ -110,6 +110,7 @@ #include #include #include +#include #include "arp.h" #include "bootp.h" #include "cdp.h" @@ -566,6 +567,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(); +} From patchwork Thu Jun 27 11:39:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953226 X-Patchwork-Delegate: pbrobinson@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=AMJpL+TU; 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 4W8xV76bmcz20XB for ; Thu, 27 Jun 2024 21:41:19 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 15A4C885F6; Thu, 27 Jun 2024 13:40:07 +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="AMJpL+TU"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 447698862D; Thu, 27 Jun 2024 13:40:05 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20700.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::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 71D7188619 for ; Thu, 27 Jun 2024 13:40:00 +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=arcselector9901; d=microsoft.com; cv=none; b=iwBvXPC5NwwF2ZcnFzYeY0jSM7eHkkeKBz406pp8A9+OO+GfEfAYo14OXFvgV0IsdNyd57meZImkqatcmoJlRMXFGnA6XGZAcKZYI67G1QzLzzySMOLckhyl8Zq43QD1rX2JrSLUn2gj+TXa4RTvTM8m2cJjrlaNZDdD1hSGS+DEMHVTVtXQEm5c40gaDyBdDaULUl1hKwIJAWv+X1rEhkfUa+gRuBK8J5n2MOzd66dXqBmbiNY6lH28QS1nuoke3Asyd4v/xzva+9w4GpiY2/DgBm1QH45YUyoa7qFXRXlXq3DByEjSS9AwM8DyUdwrVpaoZtB0C5FKjsc3PL3i9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=CuZoXxas9R27ViFkmKoWwh/pF3V0Lh5Z29bXOrJ0V9c=; b=ANexN49Ptg04d/WvK/WyvStedvAQOuakjw3WIYvaZmH2bR2tGWDMiDjL2f5V+fiivqyA0at71g2Bf9K10kYR4Jeiock7ofSnhnomVimNznu4hA1TIRf8Mt87P7sa5UlVNzPYmJ7Pholzv4BlptqqTkeytPLp5nVgGfOgJZ3rb9B4BHW9an6xoLb/+XPoR1n2sR7gSa1AJ6G8H5NrwaanNrYmrYTdxll7VgDzOtV2ByhUeF5+HtCaDugW80EuzSQBUsEVpyBOnXmNd/ZB0901e1fN+wnRxkBKffaN1KxdpCHxS/DzBQ+FG8h6sUHMKwtdMKm73fu1m1kFrNl/taqtfw== 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=CuZoXxas9R27ViFkmKoWwh/pF3V0Lh5Z29bXOrJ0V9c=; b=AMJpL+TUokqTFdrtUDuM4mAYKy7X/xG6uqEQJC9K4DXx4Obiw9e2bOHMgB1Jgg3RW9tjNBivaFi2SZdQXK7U3zMRb2KBhoKobWt//W3dzBXy46j7pvVfCT4NzPqy3YEMWu+KrkKs89JiXLJKcqngyG0JqTCSH7RJa4rL/ODh1B9YOac5MuEbooQWS/cVqRqq0rQbtIHb0V5JJ/VTUiNuCI+cilQE7f6XuueBFxECnT0f7KfO7XJieLeCWvhN8yj+k5xZ1Il0RWo/0GSt2p+9ATsMs+xbrrQFS0hUI4RxWAMKUsbePh8cGWIpvdMEOpSlMPUt+vhHcoVJWpLpI7TEIg== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:39:58 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:39:58 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 08/12] net/httpd: add httpd common code Date: Thu, 27 Jun 2024 14:39:35 +0300 Message-ID: <20240627113939.100620-8-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: 86e191e3-d3ad-4d4c-585a-08dc969ddf98 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: Z0HdplPQcF9gn9Xempe3BHtVbyzW9EESuLHnw20xS8kAOFHpjyly+QBnB9V58PUE6BdYPhTMnIsv6xtz+iG6zQYyCj8fmxRZY+n+8V+b2yzsK6PjdV/p3gkfhBbKRnBuWTvIqbAnk1DOl+lw6WQSi07c161OG4edZHR0Lkl4Me9MtfjbuRjNMkAI2h65a6zQtfvaxW0SOZsPbCU8MtH6WP8AEXiHKsTvF7zIky913zM3O3hWMJd2jRIHkzlYZWNIuPmnyvI0PtgSdKZys2U9D+padm6GxInmFmSg5hBGKKYnAfC4yVfuHNBZTc6lvl8OSEGT84XNXHJQmogy0Ltge8uaH0FLAiIqImZ+ZpiVp1i/WPXOvpMa8SPhh0ae2rkcyluupd/v9V6ya8QSWPN6ijsne6cjJw7ECF66ckTmNxA2jz0JXZ/8lMb/6lbe/zRrYis7XaU6ndIgITTRA0QS7LDh15b/0Z+Hd+k96Y/U7O6LKkAoD29xLaq2r+8J9CLQ1y242Wb4YPbfHBeH7eUs3OmzhdiNtsZ2kKJdhjRobbJQgeHPpxZ2KWryWJ4zw0RolqiBkeuBH0zoltqHZIc9ZjWJtXv84++t5+rto4iCdtDWeWgfS+R9+wGX1V+9ilGYco8It1MuerAWa0+7jIaqvMLmt2FdkE9dBgWT48yJ+fIEfNVks08B4GxCUNTpaRY5+gmOcJSOf8duu1U1iI7Qc9s/sfAaGcdQ/NHsKcd7Pt96fNCOXZWaMtZUacfisE78JKjo0oweOMLsTGecOd8X1hHa7HIA1uE1NzZc800kSUAwlVK0j2EYf0WK0dHYqLVYQDwyKm7lVTWR1UvRKeXT9MvkKbWAl1/mYxrnoM32UI7KR6KPO3Ewt9UVYOrQ8TgcATiB22MMmKAjZ2M9CsLzfteLNgjWxhOlSfjPnNIWG/QWuNcfQgoCESAZad2tZzwRGHAnV1vrMv3piA3IkuOZ3ezXC3kk0gUt/ud+PuhSkzafhPRx0D2QYyWQgLYKz+JGf3qRfNSDJILGugzAjwEN0F8bL6RrbB1RZl5QhHD6Onp18PO9xQ4Dm0vmNsuMg7iiUOGSpc7qofi55XQEeXzJ01ND54DH7bCQxg1k2BIO7nBpFovb/Rwho/IBAlapdiH7fADiIV819fOmisH8hhvoGCCDVKONHfa5GXAsEjH7oXqCZ2EJdOlaGsuJd00989VtMsznMBuKwRUSAsr9cVPYnaUZmz/YsdK/t37/Iydly4SjH3/iXDviZ7/wWLQdRlNX5awx/hDzHSKKz2QwFQ0/2QRPT/bEfZDm3q2oP5Oh4B2xOXlQcZ9ZY/mGA448YkliNI6QwrbrjwIayDyq6bC0XvFEZaHH0D6kqfrw9qyFlDpTNTWak6+Vkzpjq+hmQ37Tube09hgXQ0YhVO+CUiNFfasncP+HyKu4/R+q9yDCxZQ= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: e0qeMNav1iI4ggYcMmIgVZxJ85XPBn9MqCFDh/P+MqsXDqOW4jbr41N55uuu7CswzZOoy8U7rvwzaK2dE/XwIgSDYxFoxTrZ9ucDnMtvbxPHtIZCPQMJKnhE9z5wk6o9pUenuwoq4DQk6wWcGBgICWzt8u5Gn6RaO3fNWA7X9q7JyFtDJapicZBArLmen+yE/V1Oa60qEzq2/nbQxGjdSdT2BvrYcLB3h5Ogmjy5NNRpGt2fsKUKxvWY/ii6xk+g+exos5cNgbD+Em4j3/YT/YkCEVnrx5tSwYebxm4iaQUm40gMp4PpvdX8qEC8XzRFKQHlVz0H7zuCPU6Rl3nBtL0zpzrKciSM3P2To0a665vrTEciNftMK0652cGC5LynBKIn8sfGNYJHxR+q4/JT2OZGEAjV6px8knHUToWnwqHvsyjBlTDaWNrDJ0pw5d0WmWx155LGaTfPeF1kTEGvkuw3g0Z40jjDET8PfV06uvrtYdB31btyTB5dGpn9AIF3GYbVYyGUO1lRrYeSupDd5mooL/A+V4GMGJzN3JitLphdKDK3HyA/RFdTIypg0HPCCF9OFSb1v9ldwTXCs4Ck51UuN+Y493qRSNp60lfJ2V2FYCUX3QBfP62r2B+UECsDNTtf0D+Fl+YFvNnJRPafEKnEnKxtQnpGA8qrKtGQRjkq4/fVoKWagmgCHCxYXVo0FsUWPSuSSB3R3UD1chdec+LNPOWiG3AJRBR/warjlBitEJeE1tZppTNQEL8lMbPx6lhx4RQuLu6n6JGwDiX4d3r5LHZ30UuWEIrQLNINoeRa+WcKVB9re4s+mUTQazjvqYAtLYMXPZQZcbNp7BqeTw96WG4faK4jCuTWyiIe51rFzm4VpV4yxUzGVJ2TYkmz7Bmyt6px9zBgeK4D2zDuh0ADfGIjnnFecFslVOlBrg8WMFpGC5bF2WlbGi5DrgVb+uAY73RbRy/y3Cf9GkHf3LGfKc8xvXBLLSo1H6awujkpcuv/1Rs2gjeTDoIAEOPHuJ6DnG80TvM2JWSO/43y9dqcDZGeu4/ih/ez1WptmIG0bqbFxgg5GFvpAy4DFDfD9gQobmOdD6C9q0JK9KnaTmbUYQJEbXI9SK2Clo5vxlnl4Nr9vz/BJzOndNHMfI6k+BLqcjoOx8H+iyzgmUp6fY/WVdSsjEYAU7719PI5ujve5o8vBhATY7L6ipnQ0d8Y3ptFOUNnVeoznEyvtfPjPt03oyXP+Oh13BW6+UubKpQD0VByK8lpPYMnK91gjS9xecrtJ/Tl/CkBChyfZ6xfhgTAb9LpxKuTw6RUVinJK03pgkkJlzD8pLITQOPVUUBBduC71gxokBsth0IOK1IhuUqe6uIJQWXvP1PGw3DLU+j3md9ZHdOz95FVToeaFVTZfCi/qL0fOxBRuqEhD4ikyR0JjqDzktm7FVxhYipnyLwiQC74VXycN89Z0klaQ9KshiN8OV8+IHBpH9nr7SGOLUTEak79Ww5D4JpjpU6kqucAE3rm1g0tDjZCLZzq6U53ro/cYiIqScSNk6pH6Vs7UOJbVFZ28tn9DMlaybxjJnYzEoVBnompULGVTmWDN6WhaInLD7ztRLYaVkxb0lvKmKTqJNGJhm8Lj899Qi3aL7w= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 86e191e3-d3ad-4d4c-585a-08dc969ddf98 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:39:58.6663 (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: zstV5003GTqrirrMP+N+noiZEWTGFy2JPmj3Fe1xHLz/2eTiO6S3+f8GAlfPW4cdMogX4IhWln3DwMWk1VQehDnW4m/lJkrXES9DlmcApBY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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 HTTP/1.1 compatible web-server that can be used by other. Server supports GET, POST, and HEAD requests. On client request it will call user specified GET/POST callback. Then results will be transmitted to client. The following restrictions exist on the POST request at the moment: * only multipart/form-data with a single file object * object will be stored to a memory area specified in image_load_addr variable Signed-off-by: Mikhail Kshevetskiy --- include/net.h | 2 +- include/net/httpd.h | 64 ++++ net/Kconfig | 14 + net/Makefile | 1 + net/httpd.c | 695 ++++++++++++++++++++++++++++++++++++++++++++ net/net.c | 6 + 6 files changed, 781 insertions(+), 1 deletion(-) create mode 100644 include/net/httpd.h create mode 100644 net/httpd.c diff --git a/include/net.h b/include/net.h index 235396a171b..6debbf8ed2a 100644 --- a/include/net.h +++ b/include/net.h @@ -516,7 +516,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, NETCAT_LOAD, NETCAT_STORE, RS + WOL, UDP, NCSI, WGET, NETCAT_LOAD, NETCAT_STORE, HTTPD, RS }; extern char net_boot_file_name[1024];/* Boot File name */ diff --git a/include/net/httpd.h b/include/net/httpd.h new file mode 100644 index 00000000000..ff0dc93ecf5 --- /dev/null +++ b/include/net/httpd.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * httpd support header file + * Copyright (C) 2024 IOPSYS Software Solutions AB + * Author: Mikhail Kshevetskiy + * + */ +#ifndef __NET_HTTPD_COMMON_H__ +#define __NET_HTTPD_COMMON_H__ + +struct http_reply { + int code; + const char *code_msg; + const char *data_type; + void *data; + u32 len; +}; + +struct httpd_post_data { + const char *name; + const char *filename; + void *addr; + u32 size; +}; + +enum httpd_req_check { + HTTPD_REQ_OK, + HTTPD_BAD_URL, + HTTPD_BAD_REQ, + HTTPD_CLNT_RST +}; + +struct httpd_config { + enum net_loop_state (*on_stop)(void); + void (*on_req_end)(void *req_id); + + enum httpd_req_check (*pre_get)(void *req_id, const char *url); + enum httpd_req_check (*pre_post)(void *req_id, const char *url, + struct httpd_post_data *post); + + struct http_reply * (*get)(void *req_id, const char *url); + struct http_reply * (*post)(void *req_id, const char *url, + struct httpd_post_data *post); + + struct http_reply *error_400; + struct http_reply *error_404; +}; + +/** + * httpd_setup() - configure the webserver + */ +void httpd_setup(struct httpd_config *config); + +/** + * httpd_stop() - start stopping of the webserver + */ +void httpd_stop(void); + +/** + * httpd_start() - start the webserver + */ +void httpd_start(void); + +#endif /* __NET_HTTPD_COMMON_H__ */ diff --git a/net/Kconfig b/net/Kconfig index 5dff6336293..424c5f0dae8 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -243,6 +243,20 @@ config PROT_TCP_SACK This option should be turn on if you want to achieve the fastest file transfer possible. +config HTTPD_COMMON + bool "HTTP server common code" + depends on PROT_TCP + help + HTTP/1.1 compatible web-server common code. It supports standard + GET/POST requests. User MUST provide a configuration to the + web-server. On client request web-server will call user specified + GET/POST callback. Then results will be transmitted to the client. + The following restricions on the POST request are present at the + moment: + * only mulipart/form-data with a single binary object + * object will be stored to a memory area specified in + image_load_addr variable + config IPV6 bool "IPv6 support" help diff --git a/net/Makefile b/net/Makefile index dac7b4859fb..c1f491fad02 100644 --- a/net/Makefile +++ b/net/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_PROT_UDP) += udp.o obj-$(CONFIG_PROT_TCP) += tcp.o obj-$(CONFIG_CMD_WGET) += wget.o obj-$(CONFIG_CMD_NETCAT) += netcat.o +obj-$(CONFIG_HTTPD_COMMON) += httpd.o # Disable this warning as it is triggered by: # sprintf(buf, index ? "foo%d" : "foo", index) diff --git a/net/httpd.c b/net/httpd.c new file mode 100644 index 00000000000..31c10843a44 --- /dev/null +++ b/net/httpd.c @@ -0,0 +1,695 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * httpd support driver + * Copyright (C) 2024 IOPSYS Software Solutions AB + * Author: Mikhail Kshevetskiy + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HTTP_PORT 80 + +#define MAX_URL_LEN 128 +#define MAX_BOUNDARY_LEN 80 +#define MAX_MPART_NAME_LEN 80 +#define MAX_FILENAME_LEN 256 +#define BUFFER_LEN 2048 + +enum http_req_state { + ST_REQ_LINE = 0, + ST_REQ_HDR, + ST_REQ_MPBOUNDARY, + ST_REQ_MPART, + ST_REQ_MPFILE, + ST_REQ_MPEND, + ST_REQ_DONE, +}; + +enum http_reply_state { + ST_REPLY_ERR = 0, + ST_REPLY_HDR, + ST_REPLY_BODY +}; + +enum http_method { + HTTP_UNKNOWN = -1, + HTTP_GET, + HTTP_POST, + HTTP_HEAD, + HTTP_OPTIONS, +}; + +struct httpd_priv { + enum http_req_state req_state; + enum http_reply_state reply_state; + + struct tcp_stream *tcp; + + enum http_method method; + char url[MAX_URL_LEN]; + u32 version_major; + u32 version_minor; + u32 hdr_len; + + u32 post_fstart; + u32 post_flen; + char post_fname[MAX_FILENAME_LEN]; + char post_name[MAX_MPART_NAME_LEN]; + char post_boundary[MAX_BOUNDARY_LEN]; + + int reply_code; + u32 reply_fstart; + u32 reply_flen; + void *reply_fdata; + + u32 rx_processed; + char buf[BUFFER_LEN]; +}; + +static struct http_reply options_reply = { + .code = 200, + .code_msg = "OK", + .data_type = "text/plain", + .data = NULL, + .len = 0 +}; + +static int stop_server; +static int tsize_num_hash; + +static struct httpd_config *cfg; + +static void show_block_marker(u32 offs, u32 size) +{ + int cnt; + + if (offs > size) + offs = size; + + cnt = offs * 50 / size; + while (tsize_num_hash < cnt) { + putc('#'); + tsize_num_hash++; + } + + if (cnt == 50) + putc('\n'); +} + +static void tcp_stream_on_closed(struct tcp_stream *tcp) +{ + struct httpd_priv *priv = tcp->priv; + + if ((priv->req_state != ST_REQ_DONE) && + (priv->req_state >= ST_REQ_MPFILE)) { + printf("\nHTTPD: transfer was terminated\n"); + } + + if (cfg->on_req_end != NULL) + cfg->on_req_end(tcp->priv); + + free(tcp->priv); + + if (stop_server) + net_set_state(cfg->on_stop != NULL ? + cfg->on_stop() : + NETLOOP_SUCCESS); +} + +static void http_make_reply(struct httpd_priv *priv, struct http_reply *reply, + int head_only) +{ + int offs = 0; + + if (priv->version_major >= 1) { + offs = snprintf(priv->buf, sizeof(priv->buf), + "HTTP/%d.%d %d %s\r\n" + "Server: %s\r\n" + "Connection: close\r\n" + "Cache-Control: no-store\r\n" + "Content-Type: %s\r\n" + "Content-Length: %d\r\n", + priv->version_major, priv->version_minor, + reply->code, reply->code_msg, U_BOOT_VERSION, + reply->data_type, + head_only ? 0 : reply->len); + if (priv->method == HTTP_OPTIONS) + offs += snprintf(priv->buf + offs, sizeof(priv->buf) - offs, + "Access-Control-Allow-Methods: GET, HEAD, OPTIONS, POST\r\n"); + offs += snprintf(priv->buf + offs, sizeof(priv->buf) - offs, + "\r\n"); + } + + priv->reply_code = reply->code; + priv->reply_fstart = offs; + if (!head_only) { + priv->reply_flen = reply->len; + priv->reply_fdata = reply->data; + } +} + +static enum httpd_req_check http_parse_line(struct httpd_priv *priv, char *line) +{ + char *url, *version, *data, *end; + u32 len, tmp; + enum httpd_req_check ret; + struct httpd_post_data post; + + switch (priv->req_state) { + case ST_REQ_LINE: + if (strncasecmp(line, "GET ", 4) == 0) { + priv->method = HTTP_GET; + url = line + 4; + } else if (strncasecmp(line, "POST ", 5) == 0) { + priv->method = HTTP_POST; + url = line + 5; + } else if (strncasecmp(line, "HEAD ", 5) == 0) { + priv->method = HTTP_HEAD; + url = line + 5; + } else if (strncasecmp(line, "OPTIONS ", 8) == 0) { + priv->method = HTTP_OPTIONS; + url = line + 8; + } else { + /* unknown request */ + return HTTPD_CLNT_RST; + } + + version = strstr(url, " "); + if (version == NULL) { + /* check for HTTP 0.9 */ + if ((*url != '/') || (priv->method != HTTP_GET)) + return HTTPD_CLNT_RST; + + if (strlen(url) >= MAX_URL_LEN) + return HTTPD_CLNT_RST; + + if (cfg->pre_get != NULL) { + ret = cfg->pre_get(priv, url); + if (ret != HTTPD_REQ_OK) + return ret; + } + + priv->req_state = ST_REQ_DONE; + priv->hdr_len = strlen(line) + 2; + priv->version_major = 0; + priv->version_minor = 9; + strcpy(priv->url, url); + return HTTPD_REQ_OK; + } + + if (strncasecmp(version + 1, "HTTP/", 5) != 0) { + /* version is required for HTTP >= 1.0 */ + return HTTPD_CLNT_RST; + } + + *version++ = '\0'; + version += strlen("HTTP/"); + + priv->version_major = dectoul(version, &end); + switch (*end) { + case '\0': + priv->version_minor = 0; + break; + case '.': + priv->version_minor = dectoul(end + 1, &end); + if (*end == '\0') + break; + fallthrough; + default: + /* bad version format */ + return HTTPD_CLNT_RST; + } + + if (priv->version_major < 1) { + /* bad version */ + return HTTPD_CLNT_RST; + } + + if ((priv->version_major > 1) || (priv->version_minor > 1)) { + /* We support HTTP/1.1 or early standards only */ + priv->version_major = 1; + priv->version_minor = 1; + } + + if (*url != '/') + return HTTPD_CLNT_RST; + + if (strlen(url) >= MAX_URL_LEN) + return HTTPD_CLNT_RST; + + priv->req_state = ST_REQ_HDR; + strcpy(priv->url, url); + return HTTPD_REQ_OK; + + case ST_REQ_HDR: + if (*line == '\0') { + priv->hdr_len = priv->rx_processed + 2; + switch (priv->method) { + case HTTP_GET: + case HTTP_HEAD: + if (cfg->pre_get != NULL) { + ret = cfg->pre_get(priv, priv->url); + if (ret != HTTPD_REQ_OK) + return ret; + } + fallthrough; + + case HTTP_OPTIONS: + priv->req_state = ST_REQ_DONE; + return HTTPD_REQ_OK; + + default: + break; + } + + if (*priv->post_boundary != '\0') { + priv->req_state = ST_REQ_MPBOUNDARY; + return HTTPD_REQ_OK; + } + /* NOT multipart/form-data POST request */ + return HTTPD_BAD_REQ; + } + + if (priv->method != HTTP_POST) + return HTTPD_REQ_OK; + + len = strlen("Content-Length: "); + if (strncasecmp(line, "Content-Length: ", len) == 0) { + data = line + len; + priv->post_flen = simple_strtol(data, &end, 10); + if (*end != '\0') { + /* bad Content-Length string */ + return HTTPD_BAD_REQ; + } + return HTTPD_REQ_OK; + } + + len = strlen("Content-Type: "); + if (strncasecmp(line, "Content-Type: ", len) == 0) { + data = strstr(line + len, " boundary="); + if (data == NULL) { + /* expect multipart/form-data format */ + return HTTPD_BAD_REQ; + } + + data += strlen(" boundary="); + if (strlen(data) >= sizeof(priv->post_boundary)) { + /* no space to keep boundary */ + return HTTPD_BAD_REQ; + } + + strcpy(priv->post_boundary, data); + return HTTPD_REQ_OK; + } + + return HTTPD_REQ_OK; + + case ST_REQ_MPBOUNDARY: + if (*line == '\0') + return HTTPD_REQ_OK; + if ((line[0] != '-') || (line[1] != '-') || + (strcmp(line + 2, priv->post_boundary) != 0)) { + /* expect boundary line */ + return HTTPD_BAD_REQ; + } + priv->req_state = ST_REQ_MPART; + return HTTPD_REQ_OK; + + case ST_REQ_MPART: + if (*line == '\0') { + if (*priv->post_name == '\0') + return HTTPD_BAD_REQ; + + priv->post_fstart = priv->rx_processed + 2; + priv->post_flen -= priv->post_fstart - priv->hdr_len; + /* expect: "\r\n--${boundary}--\r\n", so strlen() + 8 */ + priv->post_flen -= strlen(priv->post_boundary) + 8; + + if (cfg->pre_post != NULL) { + post.addr = NULL; + post.name = priv->post_name; + post.filename = priv->post_fname; + post.size = priv->post_flen; + + ret = cfg->pre_post(priv, priv->url, &post); + if (ret != HTTPD_REQ_OK) + return ret; + } + + tsize_num_hash = 0; + printf("File: %s, %u bytes\n", priv->post_fname, priv->post_flen); + printf("Loading: "); + + priv->req_state = ST_REQ_MPFILE; + return HTTPD_REQ_OK; + } + + len = strlen("Content-Disposition: "); + if (strncasecmp(line, "Content-Disposition: ", len) == 0) { + data = strstr(line + len, " name=\""); + if (data == NULL) { + /* name attribute not found */ + return HTTPD_BAD_REQ; + } + + data += strlen(" name=\""); + end = strstr(data, "\""); + if (end == NULL) { + /* bad name attribute format */ + return HTTPD_BAD_REQ; + } + + tmp = end - data; + if (tmp >= sizeof(priv->post_name)) { + /* multipart name is too long */ + return HTTPD_BAD_REQ; + } + strncpy(priv->post_name, data, tmp); + priv->post_name[tmp] = '\0'; + + data = strstr(line + len, " filename=\""); + if (data == NULL) { + /* filename attribute not found */ + return HTTPD_BAD_REQ; + } + + data += strlen(" filename=\""); + end = strstr(data, "\""); + if (end == NULL) { + /* bad filename attribute format */ + return HTTPD_BAD_REQ; + } + + tmp = end - data; + if (tmp >= sizeof(priv->post_fname)) + tmp = sizeof(priv->post_fname) - 1; + strncpy(priv->post_fname, data, tmp); + priv->post_fname[tmp] = '\0'; + return HTTPD_REQ_OK; + } + + return HTTPD_REQ_OK; + + case ST_REQ_MPEND: + if (*line == '\0') + return HTTPD_REQ_OK; + + len = strlen(priv->post_boundary); + if ((line[0] != '-') || (line[1] != '-') || + (strncmp(line + 2, priv->post_boundary, len) != 0) || + (line[len + 2] != '-') || (line[len + 3] != '-') || + (line[len + 4] != '\0')) { + /* expect final boundary line */ + return HTTPD_BAD_REQ; + } + priv->req_state = ST_REQ_DONE; + return HTTPD_REQ_OK; + + default: + return HTTPD_BAD_REQ; + } +} + +static enum httpd_req_check http_parse_buf(struct httpd_priv *priv, + char *buf, u32 size) +{ + char *eol_pos; + u32 len; + enum httpd_req_check ret; + + buf[size] = '\0'; + while (size > 0) { + eol_pos = strstr(buf, "\r\n"); + if (eol_pos == NULL) + break; + + *eol_pos = '\0'; + len = eol_pos + 2 - buf; + + ret = http_parse_line(priv, buf); + if (ret != HTTPD_REQ_OK) { + /* request processing error */ + return ret; + } + + priv->rx_processed += len; + buf += len; + size -= len; + + if ((priv->req_state == ST_REQ_MPFILE) || + (priv->req_state == ST_REQ_DONE)) + return HTTPD_REQ_OK; + } + /* continue when more data becomes available */ + return HTTPD_REQ_OK; +} + +static void tcp_stream_on_rcv_nxt_update(struct tcp_stream *tcp, u32 rx_bytes) +{ + struct httpd_priv *priv; + void *ptr; + u32 shift, size; + enum httpd_req_check ret; + struct http_reply *reply; + struct httpd_post_data post; + + priv = tcp->priv; + + switch (priv->req_state) { + case ST_REQ_DONE: + return; + + case ST_REQ_MPFILE: + show_block_marker(rx_bytes - priv->post_fstart, + priv->post_flen); + if (rx_bytes < priv->post_fstart + priv->post_flen) { + priv->rx_processed = rx_bytes; + return; + } + priv->req_state = ST_REQ_MPEND; + priv->rx_processed = priv->post_fstart + priv->post_flen; + fallthrough; + + case ST_REQ_MPEND: + shift = priv->rx_processed - priv->post_fstart; + ptr = map_sysmem(image_load_addr + shift, + rx_bytes - priv->rx_processed); + ret = http_parse_buf(priv, ptr, + rx_bytes - priv->rx_processed); + unmap_sysmem(ptr); + + if (ret != HTTPD_REQ_OK) + goto error; + if (priv->req_state != ST_REQ_DONE) + return; + break; + + default: + ret = http_parse_buf(priv, priv->buf + priv->rx_processed, + rx_bytes - priv->rx_processed); + if (ret != HTTPD_REQ_OK) + goto error; + + if (priv->req_state == ST_REQ_MPFILE) { + /* + * We just switched from parsing of HTTP request + * headers to binary data reading. Our tcp->rx + * handler may put some binary data to priv->buf. + * It's time to copy these data to a proper place. + * It's required to copy whole buffer data starting + * from priv->rx_processed position. Otherwise we + * may miss data placed after the first hole. + */ + size = sizeof(priv->buf) - priv->rx_processed; + if (size > 0) { + ptr = map_sysmem(image_load_addr, size); + memcpy(ptr, priv->buf + priv->rx_processed, size); + unmap_sysmem(ptr); + } + + show_block_marker(rx_bytes - priv->post_fstart, + priv->post_flen); + } + + if (priv->req_state != ST_REQ_DONE) + return; + break; + } + + switch (priv->method) { + case HTTP_OPTIONS: + reply = &options_reply; + break; + + case HTTP_GET: + case HTTP_HEAD: + if (cfg->get == NULL) { + ret = HTTPD_BAD_REQ; + goto error; + } + reply = cfg->get(priv, priv->url); + break; + + case HTTP_POST: + if (cfg->post == NULL) { + ret = HTTPD_BAD_REQ; + goto error; + } + post.name = priv->post_name; + post.filename = priv->post_fname; + post.size = priv->post_flen; + post.addr = map_sysmem(image_load_addr, post.size); + reply = cfg->post(priv, priv->url, &post); + unmap_sysmem(post.addr); + break; + + default: + ret = HTTPD_BAD_REQ; + goto error; + } + + http_make_reply(priv, reply, priv->method == HTTP_HEAD); + return; + +error: + priv->req_state = ST_REQ_DONE; + switch (ret) { + case HTTPD_BAD_URL: + http_make_reply(priv, cfg->error_404, 0); + break; + case HTTPD_BAD_REQ: + http_make_reply(priv, cfg->error_400, 0); + break; + default: + tcp_stream_reset(tcp); + break; + } +} + +static u32 tcp_stream_rx(struct tcp_stream *tcp, u32 rx_offs, void *buf, u32 len) +{ + void *ptr; + struct httpd_priv *priv; + u32 shift; + + priv = tcp->priv; + switch (priv->req_state) { + case ST_REQ_DONE: + return len; + case ST_REQ_MPFILE: + case ST_REQ_MPEND: + shift = rx_offs - priv->post_fstart; + ptr = map_sysmem(image_load_addr + shift, len); + memcpy(ptr, buf, len); + unmap_sysmem(ptr); + return len; + default: + /* + * accept data that fits to buffer, + * reserve space for end of line symbol + */ + if (rx_offs + len > sizeof(priv->buf) - 1) + len = sizeof(priv->buf) - rx_offs - 1; + memcpy(priv->buf + rx_offs, buf, len); + return len; + } +} + +static void tcp_stream_on_snd_una_update(struct tcp_stream *tcp, u32 tx_bytes) +{ + struct httpd_priv *priv; + + priv = tcp->priv; + if ((priv->req_state == ST_REQ_DONE) && + (tx_bytes == priv->reply_fstart + priv->reply_flen)) + tcp_stream_close(tcp); +} + +static u32 tcp_stream_tx(struct tcp_stream *tcp, u32 tx_offs, void *buf, u32 maxlen) +{ + struct httpd_priv *priv; + u32 len, bytes = 0; + char *ptr; + + priv = tcp->priv; + if (priv->req_state != ST_REQ_DONE) + return 0; + + if (tx_offs < priv->reply_fstart) { + len = maxlen; + if (len > priv->reply_fstart - tx_offs) + len = priv->reply_fstart - tx_offs; + memcpy(buf, priv->buf + tx_offs, len); + buf += len; + tx_offs += len; + bytes += len; + maxlen -= len; + } + + if (tx_offs >= priv->reply_fstart) { + if (tx_offs + maxlen > priv->reply_fstart + priv->reply_flen) + maxlen = priv->reply_fstart + priv->reply_flen - tx_offs; + if (maxlen > 0) { + ptr = priv->reply_fdata + tx_offs - priv->reply_fstart; + memcpy(buf, ptr, maxlen); + bytes += maxlen; + } + } + + return bytes; +} + +static int tcp_stream_on_create(struct tcp_stream *tcp) +{ + struct httpd_priv *priv; + + if ((cfg == NULL) || stop_server || + (tcp->lport != HTTP_PORT)) + return 0; + + priv = malloc(sizeof(struct httpd_priv)); + if (priv == NULL) + return 0; + + memset(priv, 0, sizeof(struct httpd_priv)); + priv->tcp = tcp; + + tcp->priv = priv; + tcp->on_closed = tcp_stream_on_closed; + tcp->on_rcv_nxt_update = tcp_stream_on_rcv_nxt_update; + tcp->rx = tcp_stream_rx; + tcp->on_snd_una_update = tcp_stream_on_snd_una_update; + tcp->tx = tcp_stream_tx; + return 1; +} + +void httpd_setup(struct httpd_config *config) +{ + cfg = config; +} + +void httpd_stop(void) +{ + stop_server = 1; +} + +void httpd_start(void) +{ + if (cfg == NULL) { + net_set_state(NETLOOP_FAIL); + return; + } + stop_server = 0; + memset(net_server_ethaddr, 0, 6); + tcp_stream_set_on_create_handler(tcp_stream_on_create); + printf("HTTPD listening on port %d...\n", HTTP_PORT); +} diff --git a/net/net.c b/net/net.c index 809fe5c4792..ca761c57372 100644 --- a/net/net.c +++ b/net/net.c @@ -111,6 +111,7 @@ #include #include #include +#include #include "arp.h" #include "bootp.h" #include "cdp.h" @@ -575,6 +576,11 @@ restart: netcat_store_start(); break; #endif +#if defined(CONFIG_HTTPD_COMMON) + case HTTPD: + httpd_start(); + break; +#endif #if defined(CONFIG_CMD_CDP) case CDP: cdp_start(); From patchwork Thu Jun 27 11:39:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953227 X-Patchwork-Delegate: pbrobinson@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=FQ44NDu/; 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 4W8xVM3TCdz20XB for ; Thu, 27 Jun 2024 21:41:31 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E53C98862C; Thu, 27 Jun 2024 13:40:09 +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="FQ44NDu/"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1F1A58861A; Thu, 27 Jun 2024 13:40:06 +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=-0.8 required=5.0 tests=BAYES_00, CONTENT_AFTER_HTML, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::701]) (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 A8090885E7 for ; Thu, 27 Jun 2024 13:40:01 +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=arcselector9901; d=microsoft.com; cv=none; b=ACFP4stcQ5teTtRM2Pa4Uw6ZYKzNWZRKYsaDyWE/5Do+KdL7qEtXTxCqILC8Sc59OmpKsmWS5XKGxHPSJeY10bwZ31chha3veG9BpNwrUgjhh4D8WPoby3fG2o6SonEGcEwSLL8LZf/nhOa8n2quauCecKreXiyNx44MMXArKUT1/9u08LhGuzCDXcPWNr76crig/xw5oa3dPO3XYDwVkn5ln5gU8pLKuEYRVqRG7sr7zXnhkDKd8r+chgfc7W3gPj9ZPzD16HkBf/yraoNXwTcq/u6ZwZsjw10qAIoMT+MUY/rQ2sT8zXT24gB61CSnBTDtd1dG4oelB8bn+EX9Yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=eP6uG9qhaM0zqflh4V2LCmovCnLOEH3UDDHo12ZY08E=; b=burqGUbthW+o3Gn5mypxH7Y2f2QWuvd6qy89XGR8sc04ykz9n6x3FuxAfl+J0oo3WxK9mE9/Yb7/cM2FqsyllQacK9yQ6OlnOumfmkZu5NJFlk+AxeJeIX1clGdwH2V0weqaXYsZjbGomO4Cq1yS2L3qbYnSDmvX5FDblTShG2S+JeyHsqAzr+XaJXWokvJClKHArgZOCbbD44zaG0SjaezxZL6aQhbTJBhhgPjPIkUEIFwMNSTMDUZ4REKbNJo2hKwd+InMHpIEjw+c5hYmUJn8edHbueh1QXA40Nqq8Uv6TabW5WBqDCVakwzGvKunQWLm0dQ+6kqLcf1vo1Ab7A== 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=eP6uG9qhaM0zqflh4V2LCmovCnLOEH3UDDHo12ZY08E=; b=FQ44NDu/BXkUPs8amBmPR7wm7sdx8IUPMvNlvVFwaweSQq0Qy0sdQLw9boWbO5c2vuQzH1ZQ9f90JcZapOm99oz7J7+5oxLm7s2LltrUEbd03TyW9DscGfNjLvNlXcWVYACRR9v66qse0q05jaWK4lHNrCEG7nEHnc07SlgNSZun733CEC0e2uzZ25qB8ia8/3Y9UisS+oHxMAJNfZIBMDkyO31hZNBiLZlU2oNwb5UgrcexKFITcKbMCoN2hHxoLqj3srxwHCnE408rwUezJOKip3hsQs6V3KBJEtGgPe9zl/9RbYpMaKuZE0tv7S9ZPq75PPj0kpR4RXrmpcKFBA== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:40:00 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:40:00 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 09/12] net/httpd-upload: add web-server for file uploading Date: Thu, 27 Jun 2024 14:39:36 +0300 Message-ID: <20240627113939.100620-9-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: 213774b4-b67d-4293-8dcd-08dc969de08a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: 6ZO8A7Oo71tT/ICmHVPIWOoFD9QQDgkBYWnp+j426YsgbHaFF2x2QZyf9hzr4ILwjnj6GjecXqA9wL0HpGpvURmaDzu4egvFWoK8HXiNGXhlvKMcn9jUixuzFtC98iQpHanLRQ6MZCDeJ7cLg/KgjlTY8g+moBJ7bnGXAwfHpaGki+rM6FsVtoqj5uxr45Acqo9VvAp4+zr7kiwdCuV9UPYvesZhwhb3uPoypgamTv0z/eOdAVovtXUW4FCt3iWYd3xZBDzjlubahblCtj+fbVfigMYy2I6/EJwNTRRUl8K5+qmccdUmJh3dwBkgn3eHFDbEQfjn4HcTxlwLpiqbLpWeipeUKsNtPOi02rcuiyxVQCYi0122c9h5QjEeqXkpGBx6xnP2ChnzxwZPMdBS8Mo7C5mRH6RZMvogv+ilOU30eadk5J3qXu+b8vJ2YGjZGnoVv0wLSv5HWE9UTQEhvz4ey833m3yHXmCxE+J4NTZhs8ipJggEviHFgYVym53rzJ0fKp6t7eiRUkQnR+oCRneQZ1FxG6121zXA+BI7PMmBTxjd/jo7ugWLGkRZRpcD85T5b3OGJg3LRYOyNQtxbYr8MhC+Yoh/cIItBrlHZk2EmPbkfOqF3TKkrMpJEx34IfWIBYB52ema0F0PUs73nWKoDLASEvS42mkO3gTKNusmmptjPwMowWaHGEbgK/xrmun91EAyOcx5cmjy00QDiG/O/oPI/wp3DOO4nzRxjqz1RekpHPFUETcVUNTT6DTl5wwhh/InzeZQzrF+ckpMxuyXTXoffIqRKGY5nG53wPVYV+3I3BQASEk/HZsFPqkp4AfMiRSgDwxCwe/DImtmqC1/4Rcdqf4HT2mXulCalWSOc6kNfGn0hiCjftEl60x7IJJPKzenAyDc8amn0kVHVkTrkl10fdkJI5AaRekJOPtkwPKu0djIFX5Ds2CxhkGyKrFjuTsHdXYG6ExPmgc77RrTQ58UHBuIjZMVD8U7zxEmiyydnkDaZcmyc2n7v819FcRKPopkwNuxyjE/Bewk0ZgRmtsk+FzX90AARZ3m5MiBbo7AerX23hNBPV2yP9D3RYcSPPQZCaqkwRXsYDAIfawtFOemZaXk22D8EKWCA8ZdqVHsNKmUgJeXXWCRqEer4rmuGdXyL9aghsUW1bHGK79FS9QjiMqUlwlAApdygsCjT4HFV3I6HRtk2JdRVeTGUHt2besfBHo3m4tV5y7rXriuH3xAa0FTzMgSDztqro8uZFCJsJLXnuuZqlXfWXEaH1YKRxR5lx7bT/K+AKo/MLInJrAUw7dNDYyllVw6vp96xUyeosDgsbEp0xznZy/ScQRcFHYa0c2AYWv4xmB7lvUDvkHrAzapWRsOU30yd5QndzTcSg7JDyuOR5LWK/GAJexm9Wo8t/o74InQqGsmg9eo5/NBly8RiS6t0yzMBes= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: j2JVeH0QsLHnVXSKxRhQaXLxAoQND+RoHDIy90uVh+rxO42aTSNCwU3tQA/70OFQUOMygsu7igW1v1MJ+bF7PnBJREe0pCq2pwrRDRXYCiRkSEHqIfrNDw8zLLB0bWq/ZRjG2CNBrSJAx4OrtoA/DmCY2ur/cCaiBAqfA9QvToACPFh6ExJcAnP/yWArn6hbq40jhD4ymdPG8zY5dspmjVjS+jMm6xcDhmb9O0CDlVPIlXaplkXWWfgPVax9y6ZWDYTXMkZKRYgNGmeY8gjOFz/ASL1WRnkzfwMW9If8YNbbKf1CIyEE6i5ywQW9QcCqDHL9MI9QK3Zzt/tCsUnxYQ4U9J0hfX65U8A3WH0vUWI3Z2G/hU7ogVXwEgObBORYfV8biIsdbsAQwnjoacU+00nKF6uXsvExISm0Oc+CEIsdK8lXpeZjjUAEDt660EgcXrsNh0AVrANrRa77QQcSLzAl6EJhrVt4eicR+xvM6joFUWYZhRPs7BNdeLHiQ5mx8tvSEZ+fE8CKmKbmykyQQ/K6nGmuF5IjE6loB3YFlizAUC/S6zZbuFPLYB5aVoSqrXoS4pLgt0tTsK+GGo85fevo87ZMSgLxLmYHmk2lH3JGnUxeohd4VVFQwWwTVUkwHoPDnlkJQfgfgCPWUzcFR2U6DosDU6ZZ8Tjw+HLEmrNiKrRLrFusL0ez0ByAvg/Pqde+S3kONCXSLZvjDmWwttLIWc8gAQi4I1in5oYfy0H0rwkqSLuA8jIFDOx8xxI4ryWAlI+TKBtWP6lL2ZZPYQhp5Ts8amXc24TK0WHWIfuuq5HH84WfAAPkkPOPGL/uVyYdVBEy6dXN60oSF2TpLyFqKWMRxmiOi5ABw2yhpDblZnmtemrEXW/9TpFRDQluqJaVZtuqUOTPXnNJmP5BVWkqqw4pznicoPm+RpkANpx1RFaj0CjZV8sp2kqEs1BP1D3ZK/s1gcNBLhb78uJmBGO6DVCKcjZGfM4d4hPd2p1bLCkS0b4fylYPaRhMOfP1l+X6trLsp7IAKFplY8V8kWMauiQIrOLevwSke3bqvKVVxKwJ9l7i6g6HZnOrCzhiRbTKl+wOjjtF/9B4BbLhi3SHoYstfE2gn0mKvVVe/AofuwNLfR79qASXpB3u/7UJipI3qc622xdpW83eQKxdGQJEAPuf5kDkjyYdsT3DguZ7CHhb4I1oqkMfHxFgtTWxDDWtGzVRj/GPf3xbLXTnO2TQT8OVXBnx4vAK8xffy0KIYm8hdoHzbhTzvcqhpUyaQ5Dms5YE56iMajvcav7nUOm0ms0crxe0IYzbMVzGlzbFev+Tsrur0LekATTJgiXNUwmzRM/jdekhVScs2V2ifgzFuNAs5Xa+Leso4cTtVWaL/H4cOruAcBp5QdSk/4QoaJG035CFhULnQIV7sH90+VQ/hlFcNvXgbzInPjBYgyICLsisWQcCLH7VZG+18lSUWasMop7m9Kwr6gznacTTWPM+P57caw/a5B5J6Fk2SYlThTPCVoq5HRVatAPHrRDGZpFais6a/8Dsz//qVhwFeuWtTvWRfcoSGw49PoMU7rdVPvTLvDWMWtNbhVKy1uMuqQDYmQlFNcbyebRL6lftXR2Dc8w5qDIEc4cOIbcEr2k= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 213774b4-b67d-4293-8dcd-08dc969de08a X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:40:00.2522 (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: b0eZ+XvE6Naz81dQ6D+uMvwqNJH6lLxKVVkT/y8TaDSFAf7JBGPxQ8xi3OFQY2TUpOj8bLliNfUK7iVmxA3kqR8grgQqWjiJ7YsyGGqWivk= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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 --- cmd/Kconfig | 14 ++++ cmd/net.c | 20 ++++++ include/net/httpd-upload.h | 12 ++++ net/Makefile | 19 +++++ net/httpd-upload.c | 123 ++++++++++++++++++++++++++++++++ net/httpd_upload/error_400.html | 9 +++ net/httpd_upload/error_404.html | 10 +++ net/httpd_upload/index.html | 14 ++++ net/httpd_upload/upload_ok.html | 7 ++ 9 files changed, 228 insertions(+) create mode 100644 include/net/httpd-upload.h create mode 100644 net/httpd-upload.c create mode 100644 net/httpd_upload/error_400.html create mode 100644 net/httpd_upload/error_404.html create mode 100644 net/httpd_upload/index.html create mode 100644 net/httpd_upload/upload_ok.html diff --git a/cmd/Kconfig b/cmd/Kconfig index 00cc13e2006..e5d2852168b 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1997,6 +1997,20 @@ config CMD_NETCAT netcat is a simple command to load/store kernel, or other files, using netcat like manner over TCP. +config CMD_HTTPD_UPLOAD + bool "HTTP server for file uploading" + depends on HTTPD_COMMON + help + HTTP/1.1 compatible server for file uploading. + +config CMD_HTTPD_UPLOAD_MAX_SIZE + int "Maximum uploading size" + depends on CMD_HTTPD_UPLOAD + default 209715200 + help + This sets maximum size of uploaded file. Real transfer will be + slightly more than this limit. + config CMD_MII bool "mii" imply CMD_MDIO diff --git a/cmd/net.c b/cmd/net.c index ecc1b49f52f..22e9d1910b6 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -22,6 +22,9 @@ #include #include #include +#if defined(CONFIG_CMD_HTTPD_UPLOAD) +#include +#endif static int netboot_common(enum proto_t, struct cmd_tbl *, int, char * const []); @@ -230,6 +233,23 @@ U_BOOT_CMD( ); #endif +#if defined(CONFIG_CMD_HTTPD_UPLOAD) +static int do_httpd_upload(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + if (argc < 2) + return 1; + + httpd_upload_prepare(); + return netboot_common(HTTPD, cmdtp, argc, argv); +} + +U_BOOT_CMD( + httpd_upload, 2, 1, do_httpd_upload, + "starts httpd server for file uploading", + "[loadAddress]\n" +); +#endif + static void netboot_update_env(void) { char tmp[46]; diff --git a/include/net/httpd-upload.h b/include/net/httpd-upload.h new file mode 100644 index 00000000000..a80df214668 --- /dev/null +++ b/include/net/httpd-upload.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-2-Clause + * + * httpd-upload include file + * Copyright (C) 2024 IOPSYS Software Solutions AB + * Author: Mikhail Kshevetskiy + */ +#ifndef __NET_HTTPD_UPLOAD_TCP_H__ +#define __NET_HTTPD_UPLOAD_TCP_H__ + +void httpd_upload_prepare(void); + +#endif /* __NET_HTTPD_UPLOAD_TCP_H__ */ diff --git a/net/Makefile b/net/Makefile index c1f491fad02..e7cbbc2248e 100644 --- a/net/Makefile +++ b/net/Makefile @@ -35,8 +35,27 @@ obj-$(CONFIG_PROT_TCP) += tcp.o obj-$(CONFIG_CMD_WGET) += wget.o obj-$(CONFIG_CMD_NETCAT) += netcat.o obj-$(CONFIG_HTTPD_COMMON) += httpd.o +obj-$(CONFIG_CMD_HTTPD_UPLOAD) += httpd-upload.o # Disable this warning as it is triggered by: # sprintf(buf, index ? "foo%d" : "foo", index) # and this is intentional usage. CFLAGS_eth_common.o += -Wno-format-extra-args + +STATIC_SUBST := 's/^\(unsigned char \)/static \1/' +SIZE_REMOVE_SUBST := 's/^unsigned int .*//' + +httpd_upload_generated: + rm -rf $(src)/httpd_upload_generated + mkdir -p $(src)/httpd_upload_generated + cd $(src)/httpd_upload && find . -type f | while read fname; do \ + name="$${fname##*/}" && \ + name="$${name%%.*}" && \ + set -o pipefail && xxd -i "$${fname##./}" | \ + sed $(STATIC_SUBST) | \ + sed $(SIZE_REMOVE_SUBST) > ../httpd_upload_generated/$${name}.h; \ + done + +.PHONY: httpd_upload_generated + +net/httpd-upload.o: httpd_upload_generated diff --git a/net/httpd-upload.c b/net/httpd-upload.c new file mode 100644 index 00000000000..f3015a37f2f --- /dev/null +++ b/net/httpd-upload.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * httpd-upload support driver + * Copyright (C) 2024 IOPSYS Software Solutions AB + * Author: Mikhail Kshevetskiy + */ + +#include +#include +#include +#include + +#define MAX_FILE_SIZE CONFIG_CMD_HTTPD_UPLOAD_MAX_SIZE + +static enum net_loop_state httpd_on_stop(void); + +static enum httpd_req_check httpd_pre_post(void *req_id, const char *url, + struct httpd_post_data *post); +static struct http_reply *httpd_get(void *req_id, const char *url); +static struct http_reply *httpd_post(void *req_id, const char *url, + struct httpd_post_data *post); +static void httpd_on_req_end(void *req_id); + +#include "httpd_upload_generated/error_400.h" +#include "httpd_upload_generated/error_404.h" +#include "httpd_upload_generated/index.h" +#include "httpd_upload_generated/upload_ok.h" + +static struct http_reply error_400 = { + .code = 400, + .code_msg = "Bad Request", + .data_type = "text/html; charset=utf-8", + .data = error_400_html, + .len = sizeof(error_400_html) +}; + +static struct http_reply error_404 = { + .code = 404, + .code_msg = "Not Found", + .data_type = "text/html; charset=utf-8", + .data = error_404_html, + .len = sizeof(error_404_html) +}; + +static struct http_reply index = { + .code = 200, + .code_msg = "OK", + .data_type = "text/html; charset=utf-8", + .data = index_html, + .len = sizeof(index_html) +}; + +static struct http_reply upload_ok = { + .code = 200, + .code_msg = "OK", + .data_type = "text/html; charset=utf-8", + .data = upload_ok_html, + .len = sizeof(upload_ok_html) +}; + +static struct httpd_config cfg = { + .on_stop = httpd_on_stop, + .on_req_end = httpd_on_req_end, + .get = httpd_get, + .post = httpd_post, + .pre_post = httpd_pre_post, + .error_400 = &error_400, + .error_404 = &error_404, +}; + +static enum net_loop_state httpd_loop_state; +static void *post_req_id; + +void httpd_upload_prepare(void) +{ + httpd_setup(&cfg); + httpd_loop_state = NETLOOP_FAIL; +} + +static enum httpd_req_check httpd_pre_post(void *req_id, const char *url, + struct httpd_post_data *post) +{ + if (post->size > MAX_FILE_SIZE) { + printf("HTTPD: reset connection, upload file is too large\n"); + return HTTPD_CLNT_RST; + } + + post_req_id = req_id; + return HTTPD_REQ_OK; +} + +static struct http_reply *httpd_post(void *req_id, const char *url, + struct httpd_post_data *post) +{ + if (strcmp(url, "/file_upload") != 0) + return &error_404; + + httpd_loop_state = NETLOOP_SUCCESS; + printf("HTTPD: upload OK\n"); + return &upload_ok; +} + +static struct http_reply *httpd_get(void *req_id, const char *url) +{ + if (strcmp(url, "/") == 0) + return &index; + if (strcmp(url, "/index.html") == 0) + return &index; + return &error_404; +} + +static void httpd_on_req_end(void *req_id) +{ + if (req_id == post_req_id) { + post_req_id = NULL; + httpd_stop(); + } +} + +static enum net_loop_state httpd_on_stop(void) +{ + return httpd_loop_state; +} diff --git a/net/httpd_upload/error_400.html b/net/httpd_upload/error_400.html new file mode 100644 index 00000000000..de654364edf --- /dev/null +++ b/net/httpd_upload/error_400.html @@ -0,0 +1,9 @@ + + 400 + +

400 - Bad Request

+

+ Sorry, the request you are trying to do is wrong. +

+ + diff --git a/net/httpd_upload/error_404.html b/net/httpd_upload/error_404.html new file mode 100644 index 00000000000..9dac22d497d --- /dev/null +++ b/net/httpd_upload/error_404.html @@ -0,0 +1,10 @@ + + 404 + +

404 - Page not found

+

+ Sorry, the page you are requesting was not found on this + server. +

+ + diff --git a/net/httpd_upload/index.html b/net/httpd_upload/index.html new file mode 100644 index 00000000000..e7d5ac943b6 --- /dev/null +++ b/net/httpd_upload/index.html @@ -0,0 +1,14 @@ + + Upload File + +

Upload File.

+

This will write the uploaded file to the memory arear pointed by ${loadaddr}. +

+ File to upload: +
+

   +

It takes no more than a second after the file has been uploaded until status OK is shown. +

+

+ + diff --git a/net/httpd_upload/upload_ok.html b/net/httpd_upload/upload_ok.html new file mode 100644 index 00000000000..8d2e561982f --- /dev/null +++ b/net/httpd_upload/upload_ok.html @@ -0,0 +1,7 @@ + + OK + +

Upload OK

+

The file was uploaded.

+ + From patchwork Thu Jun 27 11:39:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953228 X-Patchwork-Delegate: pbrobinson@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=1PiMXCWx; 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 4W8xVY2j7jz20XB for ; Thu, 27 Jun 2024 21:41:41 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5D32C88605; Thu, 27 Jun 2024 13:40:10 +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="1PiMXCWx"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 35A7588605; Thu, 27 Jun 2024 13:40:07 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::701]) (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 8E257885D4 for ; Thu, 27 Jun 2024 13:40:03 +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=arcselector9901; d=microsoft.com; cv=none; b=GjLc564lKi+f4rcJwZLUQ5A9zkNN/r4/BdxTPhXsMFCGAlUceQ9/I24i2s/fbHeQ1qgtDPeKZDiSi7DsIsc6Gub9O664+QN8p0aeiMCUWVbffZTzjeyuw2wSzHebfPax8tol+XIZ4PS/ice2duc7+Kadsbik3fQcJC9p719RUNASCo4VEORpEVoBk3u7I+QeGFKoijslaefH3bp2RuECjrFUWeYnpDlr5qjsD1o4BqIDtWNuNVDhcKy8wOODeBk7qAo7GRfOvvFxkq3qdZWbZFMImKy0x1ur4ndPOqCCeAyIaQqNKL65seVHPIHwUl7KchhoHuuagjw7b77yAtWNUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=wgBiX12vd1N27uJkxDfQ3F8Sdu73DZ7eumt1cC6V9LE=; b=fwkdKD/cF3f0hlzsH0isCKE/rF4QiIKZaYZNFzJJbugcYzgxu2b/z8YrhPQa1dICpDSMLkcNg8YTULFXmM4ajFy6STIbRXcuGTCol11gn9tu1hJHsfdpsEW8f8E82EzpyCY9NbmRcKmk6unoQFqwGdDrUlEgNyU+EyjounLo6BZBIAK8MQOC+u/8cwjM7Lyy7WOijBpQWfe/s9o9tVlt089RWpuRlDRzz5a6ZK22HBug1sUkV1HfPT4yvJb2/9oxDM9fCI6ETwP802RG5Q7wHFcZ6/lm2F3ef6pzFued1h19Fa/LSXZkCkHCdpCDIs7wNfszfx+Hr2KE73S7gi9dUw== 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=wgBiX12vd1N27uJkxDfQ3F8Sdu73DZ7eumt1cC6V9LE=; b=1PiMXCWxeeH8Yf08QKzdY/X8g8D85L4OKEK+rW0MIlrtaUTjNCzS4swuJoBiwYQls0ZkwYgoIqh7//A4tYvCClN/TZSNvX0vEcCRBggrOc0+HsuEgCtcN1NzgNNPyf7TgGG8NyE1m0/skfpFzqw3Gsohbxha6Cu2qCkx4I8RvgslGqyFfkF59wGG8hT7H8TUfSiaVO9zWTCmNOhZDh//hn00GkJP/1zeToT+3SXwXuxTTCfrN1g8LOYzOFLdaOTn0kXzDP5BqPntleJkhDz7PzoiVHpiECMrmNw2PK0s0eazrsDFqBOqgKBi87jmf1fHMgrDcEPDA3Y1CTS3qMSP7w== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:40:01 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:40:01 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 10/12] net/tcp: simplify tcp header filling code Date: Thu, 27 Jun 2024 14:39:37 +0300 Message-ID: <20240627113939.100620-10-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: dd315fe1-935a-460c-29dd-08dc969de17d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: HxpODs6RyXyHHe2zHZVKPyHGep0ajd0MBXOnju0lXowv4mV3oVNvBQ9+fmEgT+k6rVsiEw+0ZzXhkZcNNxTivxAq71+VcD0PeRMC6Z6RFqV6KMdD17NZoSsYNWza1yqK/CsAYKdH7014Gg/BzzJ5m5lLGaCs6rzVb4OT1nHcz/UlkAQ9wT4X2xmhFN1Fp9bHgHWq6q8eeuX/30H3LRXWTK/bEHCHgr9JnKhS97IVJsMga0sz5MuQKwOwTlXqaBLP3A9mtpvF2c+EwjxkmEAf+80qQ3xQNKOpMaQ08YXLmfDIdhQLnic/ej+p8ogbKjBeyZEnwylPf3qMmvLw0+rx03iMBHMvXEd6RggxpOKiW418IK3s4v9wWkU9BrOKWvB5oEuUcWrha9nMVy+xMni7lJJ444l2KXH7bG8kSjmTv/38Kldn6NOi08v2o98bzjEAYW5EQguSwUV5RRWheB8rPVErRck2aSYJPXvvBaKX6G3H9f2EKBDM/TJcTS05y3SjlFY9USJvUhwWtqM65GUayLfqFVOAcmYNVaslV+/4OrtuGQU8BsxDYMS1lWNIfxap3y30wblOy1z86nAW+/9kuvcP+yy6quCIYA132B8Xorrd594gZdg/q2K5BmNvkppZukZ5IHdP1gJ26yN2PxFTfw1hzQxdhiLd2FHmSv5d8ajCTzreyEJHW5F4+OzosUCtnbAYXxW4HWN0kG/bUvh4QD87pi9fG2MDUbJJbwJjFcTxUEtEXuaDS7DyvZbYjWD7FBclkeSLnVVAPkxJjz8fVgVXa4bx1rN6+AwC2IfjR4TYzkdAriBS0+dcZLnMVmkXzv8F/D9AemrAN2+m/Zn9yRXwg471HrFgRhNEyaRmFAcvQNwssHLkiHSC0/xfOmruqVKbbaSSpyT8BvdOvsAWpWYyLuWa6ltpjd1kd1ot1Sld0ecWhv9AuHzag9wv634kXCl73ZZcFKA7b7om4YdyErFXgif1auA2pQEAu6yEpauYWvjoEOeKF1YAK8vv9N1rd875BJhuDFjOOexQsND03d5574rHF8ejzYyRo1Za5RRn2lP7HvVFd0wrnRkCx2ejwGUDSttCSRgEq9yWCjQEF3rbW173o4jbPSTUuML1aMR90vfxaX4AJ4g7zgUrIIapWQU+FjQ69SREGw/UocItng1JVbPQ8o9ZoWo5XPCaZ+Oa/cKVpth8bsmbtjlliM3HCpLcDxY3u8Ibow7CMh33pdLpKmK3Vi1c9kPRnqdAMIOzR5OF5XQHhKHQhcMPvplUc6OjZLiTHZrgbgKJb/Tvf6I9GRBKy6b/dZttRdAXI7dcy36At9AzZzZ8JaVHAu+zQBJdMXS6passDh+MTnWg6MC6XnxKFkx9Kno6xtwYa6lNBkJje8b3B3MhOqUcjcoRb1NKMy3kcMKXmD5KbKtyHgoqdUAugW/KRpAnpDiLK6A= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 8nSrgDv45VC6tYWKLPNbIc0QEw0hN7Oe/4Ptg2tbchgEaEck7nMa2jZ5SfzVG0AaH2GLzDioBhNa7k30+sZpNya8cPB2qCkUHTji9hbENI4Mln/a53DJ/gUSj9Q0/HCMDnMQrxwQ/zel6TTbSAzj0mDYXQ1To4k7Rn8U8RJyJoZk2vKjJIq0lTQR4ADoSIWi7Qrb6jIS2RLv9XUBgULBAmm1b863AcvN9WcymrRbsB/SNvoznRaioKuSLtSsTXdmr4uDC9l1vq1V4/lboKEDtmyt7uY0HFmOrOX8JYrdmnLA0mbAzX3bOThyKLHh1Wmd4wkdNM0JAZtxC+Cv97/IAHCvpazKaSHoV9btmADJJNDpwoSmPtTuL8aQmJXs/605ms+kt2aNM5iEL07258KlOEiLVvglmx1q6LSd/dn6XLlJTvPn8AEQ2AnyL0ebzQOMwIzrv1tKqYgeDUpL64vlLkcFx+IOXNJ4ZQ6wjCs86lorHwTrLpenED98YLIs2E+uWCa8TZ8DtXxQk85E2Yt+qZT2APBvi/0pDyDFTbsVlW6/jQLo+5TO5PmFGr1l6trDPsOhiy0+BXIyZ7p4KdmlN7o7+7+5NyIa7b9iPMkXCTL0azauDqa6J7e10337yY9kgvtROb7GwBLuvYTrhikiR7xbsohVvrzYeuxiRqigfWlWykW1qLT4DprnzHqIVCVRjXVwM6tCQ1NS3wmeqotX7tvmr6qwcW8dCRR3FzLgTyuamN+B8LzfR3Ag/DxRZ75ApSmL32wBAIWtlGZTpSBPch6MbIZ9TlKm+ISiknqn3h7zjw6j2CStVEP2lxPi6kl5EboC6AQR3Oo1Z6Sp/KUwUltm/SjN/Fki+UrdcZKswbRSOb/NjAYKgnt7O8pnDum3J2vPoC1ak5s7/902YbtrhnRiLhaW538B9yTkenp4J6rZa594L+mW67lwysusIx3i2ul62BpZrE27LVSt/LS30KAVLqjC1kagVcB6CgPyhgMbH5OoM10SwEh3l8pLyVkKdZgolUTI2fRsS0GYE5blmBC4CwYYA83wSj6gkpujj/cvN4/HK5gjlzp39OJPvUKSf6mSPCtSrjunLxrCPVZg+czaeP0agwZdk9rJqONHyWgbofImWmfpyFGgEgKYH/41Oana/VQa02lG1kUV69+cV3D3qylrdVSFB8WmB9DUCbkosJL6aLY5MqAlC00Rci6alYtIJOFNdX+JKyOzS2EQqRkK4mhJWGS6GXZApRR1KEzex3L4eOA02AxPVxhJvqjwrTlCsr/tGwKtArqHyMysEQf/6Ys13ZpF3KhbD/7MRuSGP0r2psddZQC/hyrQUJe5kiYIdVgCdd7w+tTuka50ztgg8iDeSh1wz3V+tLLmn+wojZpkOvOnX+u8vusd8OLhnpJ6lh3EXamWnwEyEporDwRkLiaXDKVY+bbnQ+cWAnf1rlitzpnZcE5dlZVwkJzGG+lzlnCUzRlE9coXvDHDj33iN1c1C5Mr8WSz+51FPexCmEtt3rLPsZNBFwsTwHZtJIDz7+M15U1sWCme63ovldvhBhoKNRZWgnqGXk4TkjHuz2iz+nwF0t6YRm9ONj6HCECnxfQ1gbRqoJEXEvGtGNFWOs+hZs61yAqopGIikLc= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: dd315fe1-935a-460c-29dd-08dc969de17d X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:40:01.8398 (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: TQhhiz6mTK8o1i/0hB6LbS6yGmo97/TIE/jTMs/jeThQbl3/ZyyDp3pi90wvaIlnvEQI6z52ynb1lIPq1km2SBs2/1LS142+g69Tkosvp2c= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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 --- net/tcp.c | 70 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/net/tcp.c b/net/tcp.c index a5689a892b2..9fb80f9c2a8 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -528,10 +528,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; @@ -541,55 +568,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 Thu Jun 27 11:39:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953229 X-Patchwork-Delegate: pbrobinson@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=umR9HI8B; 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 4W8xVl3n3cz20XB for ; Thu, 27 Jun 2024 21:41:51 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id C0D7088619; Thu, 27 Jun 2024 13:40:10 +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="umR9HI8B"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A147488606; Thu, 27 Jun 2024 13:40:08 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::701]) (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 3BC288862F for ; Thu, 27 Jun 2024 13:40:05 +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=arcselector9901; d=microsoft.com; cv=none; b=fSJzyRr0z/yJIhN5QQ27Aov2sj5C6RH2jkgpgwHkDwe2AwbExJV1r+hA3CDL+4l9hTNhZDtQqEMMcFqDTeOlx6l7OkAZjPqnH8ZTeNcy9QrlEfq0HoMDJC+9SxzWHnbADkBZ9xr+uYQX8yg/Hop9RO8icuocZxUoY3DpY+IEb1c0S3RAUF8QBLJ5py75ccOS/tB5mEM3fUnkZXnASNaYj71LxDgp21NF6zN9bMyrmglNzsEySOC0KLrotZY4HV7obPagfAqPIE90STJ0ZAwwaW/g4LGdLf29+yzW3LfssGTiVJtZ32H8zbbxv7aVOsCEN/6EyulaLGZjI+PHjVBAjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=pJjX4LAK58l18HhWvO89L0+m/AcdOoRU+H9cMqw6C+o=; b=OgA0PEk7VPo+xUEkaVM657OQdi3cy4huPrZR3h7UuflxMGCRzdWHbeYpksoeZF9/mfybEp8uTqQ6cDvOtgyBdLpW4+icc1ov0PdpUaAIiwLZCiwmfbrvvLUFdqDUaIUddSPkYwU4f46Pxl97Mb3siTg2wibGpOjv+gQVcukzei2DlHNipsyaqsBxbd2VMfLa3XABuvddwRzbNEKEtThdqx9jzzLvjO8V8CbzQxxf7nUChyzEVnvpUe+ZW+jNlCFtJQnYk4uJGIBRE4xScknCc4zt51zcT0rSDH661t1Hfv9xCrUw6sUgE1g0X8OQ9J0J6/v5rkzG0siA5SwS5z6VSw== 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=pJjX4LAK58l18HhWvO89L0+m/AcdOoRU+H9cMqw6C+o=; b=umR9HI8Bdk2Uzz48ka99aw0WKeEDMAsK5oU1H4pMNca8CuXRGMTFp/DoJSeHjJiXEm/4G3qy+MtLqqSetjbxmZfCOD3O0SFcF0I44jGzq0CiI2mCjmU0IvBFV2TAXxLKtPfchnuTepptkleRN6qOXz9kM8uJU24SAi3t+Cs2Y6l+ZBkLgpXOeScPDpWeWwShXaWYYZ9qYpSZ4rQhVa9qUQkr6ShyvRP1BxgtF/wvc32QKQnYjDxqL+cylM0jDCcRa9tTzgAt14PMhSMEFdzG16LOKpsLEDepI29x/OunFiI/20E+GU3fhZCOZhCsw4AJcf7gHD/27HSPNa8EOU8F0w== 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 VI0PR08MB10427.eurprd08.prod.outlook.com (2603:10a6:800:1b8::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.35; Thu, 27 Jun 2024 11:40:03 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:40:03 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 11/12] net/tcp: add support of multiple tcp connections Date: Thu, 27 Jun 2024 14:39:38 +0300 Message-ID: <20240627113939.100620-11-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|VI0PR08MB10427:EE_ X-MS-Office365-Filtering-Correlation-Id: f0482997-6e98-43da-80eb-08dc969de26f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|921020|38350700014; X-Microsoft-Antispam-Message-Info: eqPUNs4TmQm43zXmCEje5anfbGaN0krrYilgivOJue9vTkAZsd6L/3E+7B9okl9kof5/AAK/tgFwC+yAHaUJTrafsVsptjosNw4vCBC8u8M85UmwcKjYXhpD5aaP5hKTQBRNERiBrWlI/pYaO7YAeaok4yMQTXAEKusLxzobMbNMZIFmZr3y27vfPFgBR+jpOgpapIed66dmd7TVRLP9N9h0rIw25JIh1O8xvLU0q9MmTnFLp2ftzODx4powWRCbD1pCO6jOhG2yflBu/f1zPDYg0WCOiP0bPQpmsyAlDUag5N31OckHprMqmzPvpNd3C90dUD23JEH3ZE7QoNL0nvWL8JRHzGNoAuHKSU5gerRXpPiPAmlxHQU3UJKZeoFGXcDb++BG8zysQTqN00NOI2cgPw7cdImJi2cWG2p6rixfMt6BA/H9ABK2gQrJyQNgQiWhOKrWpZP4bhlKj3isBRbmirb9xPzUUvCNIzFWySo6QrNKzuwh23UgxQFCJ7qfJk6O1v9eMhjCrvmlS4j0976KFlfYK1zo2VA9NPlhyovJn7ctv0qH4CgCp585Qbpjxq3ASvID+FuchpsubAdERyYy5qN9Q3TRyTOkXKtazt2oytk+soXiSzG9TFYo9/srq4nluYbvYkUuD9ms7JdPOENBe/C2PjoNsuDRgqUk5k4lxraaR7RajFUcZpdI7M/KB4E0RcQdnQQ9+ssoFDGbra70kLgP8N439Bxo75WmtNudfQE2oX20wmesBKd/C+SV5sV+1QouEEmQina3stUEb1uBfds+7q1M6MuDrU7OnB9yo7cAU9JCtBfsf9Dic7Jpmspz9wS76Kjk9NO9pzEOMqiaGKh5WP/Etsn2DIyb2TBXl47ELF1e7Le4diL9tGR9/8LBVf+cOcW40K/bs/8m4V5vzFk+NYerSe9FiOh8kCuYsWrWGZABDo4/boLhf7p2mY1Kl27H8oBTdyqPZEmb4PWicBHvKNQVeyjFKnZaQZo3iZsSqmiqmckS4MdLzdlLzsYoX2L+RLyi/Sx8Z3oNGiWbZr3XpJflB0anKyOUmeYBVfox7AMagPtqrvjjuxtG5JSO7cz1XMrh4hQAaLM5IlLIYW+Rk1n1J7zo5x4IIn7fDhCsYa409RrTgBFa9I7gjq5tCN6EQ9/sOPLdzCKcXabtRRgjRA2KrOauausCzcwAb0+86Syy7VfBFAte89UbEqhf5hpkVIBmITUu3bgQ76aU1vAJL5bCU+pmKTNJZ9B6WvrhaWc0sUszc0ct4xaQmLQR166jDOjCPg4SDzqUU+fV0qdXjwYywhY8ew05tDUYRZtC5jeFaL7efOWL43ogoezCxUN3PuvozbbgECpf4rVgO7ObZQ117bOUugmJfZWGtrqEJek/GVV6rUGYKHEU9z8DJbGJIhu4VEcrQUYPbwaDeaB/3Fs0bCouNKtc91A= 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)(376014)(7416014)(52116014)(1800799024)(366016)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: g+1rm24O4HWlLAaGKyMQ1/5UcOUznOHMlfuDLVuV9S3b3ljEaZSLyXr0NPAXZ/uh15WsO13L59WNs2LFRzOE5cIzO6UANuZ46mQmHHXdZZHqoTCgeqg8zK0CUq58/q8LPjAzdRyyB8AD+eQj+j1TLiz80/QpgKHjiDjzxwGPMCidb8T9xNoP065KXigAy1hN+7WmWqgYIOHq1iNwINrLHko/AspZnS73GI2IpCO45mCWbJCKIGbi8I3FJ++j8XyNBmbDaM/2rJz+95+vMoKrAqj1jj2Ejf3SI9rX//+koBtKhAdrfCN8mro65PKuFmQ/+PTIfpwKlM6YSk5Ajvcl8fxvHMCm6npRT2uKG0E/M0hPeZgoDzSFMFAuBQfvP6yJgZH5SC5cEv8Aa7ymGzwj8Rn0Fix0uaYuYjRmfEk0lhum80EbZoGkyMC59CmDb1yid3t3/DEML6wpc8SsqQjza5evRcQZJAQl6p1KfheGdKUFHgTyMLtbVxeQgfZCYVx8tXkRft7yMyEeaARWjuwn97ndQVFnSRpA432SjS/kuYuqHPkCD7cPDZ62mUTxPGIvH1C9yL1JdMfr7nV5e62J0OfodobJqswmb+uX8tkOhtj+f9WCNoAguFilyOVoSUIJqDKGkpLNpTa1Pd2tJ7W1kw9uhA7hHjMnLxlUsfFg24WEaTup6Is01AykoFgII+9H4/u79iQNjo4Y5EsxC+KUsrNHdanbdWtgNTdmDHp32SPfSiVMw2759dzloUFpOVWwuuOiwXTwxcRbPF92WjglOZzvFvOXtz0tfifze3QPYaysZY26ym6cvFAIQmDfiN0tgYyOQnY3jc9a8nuX0W/S8aqVYtvrct9nqNc1CN4paRePHq4ooMpG1FZuOzb/wVF4nWC/9RU5/dooRHJGFBbffRatVr0wbR78lSfEIW+XaL2fh5EWAU+TPEk4ESKuWeg/ROaSf0fqCgLg1ujrlsPz+Hn0uuhxwqzesamcA/47MpX+1VC6Nl3NxLCxon2RplkBiVMA8abg+6FEWugP4mkfDmajcaLtr7eMsufSPZQOjzpau86jFjbO6dOCqXL82bwBzeCi61Qj+X9gzfAU4VWFhyboZkmb/GhPRjC6ZVIeITYQtDAB12Nfj7QOsoHZXbHHKpuVdwbmnASYDleqoxRRIB5Z0QJN1wXeayArqkX81DuYQwdRCTuy/mL49oOd92LSRFW5JwjNMckvHTZlC3GTzcUnXWynZmlL5mk2Hb4Syp85K7slULq9ATigGIsompSYrsQ45WaFPhYHmsqJgtWUO1XQk13QoosTHEaIk4BKoBJ2gcuzyf1L3xV9YdoIZlw+5Mg8AX9ZG9yR6Ju/62pCmnmW+OYozjSNZdcgNpLIrNhdm7EQNf7H+MEsq3sL66UI8+42Dg4zhhz5GqVCYEt6o4yG5EoAmWm4CPhVNtNFeQi30NkLsI4gumXDym2AAVJA4eEFm9ppn11ZRy1iSVddTjbHznRy2ajsM4jCG2mCpTLSkjxtS9+W50T3dkhMPUwcp66S4yYUJ3kHjTUuFk/d9e7VFtH2fDa/GIbE1V1s82ZniZjDCv7wikVhAE8aag6v8g2bc7W7+ehl65EQuXtrRDgNj4/y8OieJdQj0hljhQo= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: f0482997-6e98-43da-80eb-08dc969de26f X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:40:03.4281 (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: Hf9ty+ag2mQIA1RFiRnqAm2SheP4haodgAtXnhmnZVaHVmygfxX2tBHmE15kzBeB/cWnD4oTIQLA9boYYe7VD4ymHPjxlH3Zx4l7hstxRSk= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI0PR08MB10427 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 As we don't support ARP table in U-Boot, these connections must come from the same host. Signed-off-by: Mikhail Kshevetskiy --- net/Kconfig | 10 ++++++++ net/fastboot_tcp.c | 12 +++++++++ net/httpd.c | 20 ++++++++++++++- net/netcat.c | 7 +++++ net/tcp.c | 64 ++++++++++++++++++++++++++++++---------------- net/wget.c | 7 +++++ 6 files changed, 97 insertions(+), 23 deletions(-) diff --git a/net/Kconfig b/net/Kconfig index 424c5f0dae8..e46d519f507 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -257,6 +257,16 @@ config HTTPD_COMMON * object will be stored to a memory area specified in image_load_addr variable +config PROT_TCP_MAX_CONNS + int "Maximum number of TCP connections" + depends on PROT_TCP + default 1 + help + In some cases (like httpd support) it may be desirable + to support more than one TCP connection at the time. + As we don't support ARP table, these connections MUST + comes from a single host. + config IPV6 bool "IPv6 support" help diff --git a/net/fastboot_tcp.c b/net/fastboot_tcp.c index 30eacca8d1e..dfa02709393 100644 --- a/net/fastboot_tcp.c +++ b/net/fastboot_tcp.c @@ -19,6 +19,12 @@ static char txbuf[sizeof(u64) + FASTBOOT_RESPONSE_LEN + 1]; static u32 data_read; static u32 tx_last_offs, tx_last_len; +static int connections; + +static void tcp_stream_on_closed(struct tcp_stream *tcp) +{ + connections = 0; +} static void tcp_stream_on_rcv_nxt_update(struct tcp_stream *tcp, u32 rx_bytes) { @@ -96,10 +102,16 @@ static int tcp_stream_on_create(struct tcp_stream *tcp) if (tcp->lport != FASTBOOT_TCP_PORT) return 0; + if (connections > 0) + return 0; + + connections++; + data_read = 0; tx_last_offs = 0; tx_last_len = 0; + 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; diff --git a/net/httpd.c b/net/httpd.c index 31c10843a44..ad13b155912 100644 --- a/net/httpd.c +++ b/net/httpd.c @@ -85,6 +85,8 @@ static struct http_reply options_reply = { static int stop_server; static int tsize_num_hash; +static int connections; +static struct httpd_priv *post_id; static struct httpd_config *cfg; @@ -109,6 +111,12 @@ static void tcp_stream_on_closed(struct tcp_stream *tcp) { struct httpd_priv *priv = tcp->priv; + connections--; + if (tcp->priv == post_id) { + /* forget completed POST */ + post_id = NULL; + } + if ((priv->req_state != ST_REQ_DONE) && (priv->req_state >= ST_REQ_MPFILE)) { printf("\nHTTPD: transfer was terminated\n"); @@ -119,7 +127,7 @@ static void tcp_stream_on_closed(struct tcp_stream *tcp) free(tcp->priv); - if (stop_server) + if (stop_server && (connections == 0)) net_set_state(cfg->on_stop != NULL ? cfg->on_stop() : NETLOOP_SUCCESS); @@ -334,6 +342,11 @@ static enum httpd_req_check http_parse_line(struct httpd_priv *priv, char *line) /* expect: "\r\n--${boundary}--\r\n", so strlen() + 8 */ priv->post_flen -= strlen(priv->post_boundary) + 8; + if (post_id != NULL) { + /* do not allow multiple POST requests */ + return HTTPD_BAD_REQ; + } + if (cfg->pre_post != NULL) { post.addr = NULL; post.name = priv->post_name; @@ -345,6 +358,8 @@ static enum httpd_req_check http_parse_line(struct httpd_priv *priv, char *line) return ret; } + post_id = priv; + tsize_num_hash = 0; printf("File: %s, %u bytes\n", priv->post_fname, priv->post_flen); printf("Loading: "); @@ -660,6 +675,7 @@ static int tcp_stream_on_create(struct tcp_stream *tcp) if (priv == NULL) return 0; + connections++; memset(priv, 0, sizeof(struct httpd_priv)); priv->tcp = tcp; @@ -688,6 +704,8 @@ void httpd_start(void) net_set_state(NETLOOP_FAIL); return; } + post_id = NULL; + connections = 0; stop_server = 0; memset(net_server_ethaddr, 0, 6); tcp_stream_set_on_create_handler(tcp_stream_on_create); diff --git a/net/netcat.c b/net/netcat.c index ea225c68c87..cfd39fafb61 100644 --- a/net/netcat.c +++ b/net/netcat.c @@ -23,6 +23,7 @@ static int listen; static int reading; static unsigned int packets; static enum net_loop_state netcat_loop_state; +static int connections; static void show_block_marker(void) { @@ -34,6 +35,8 @@ static void show_block_marker(void) static void tcp_stream_on_closed(struct tcp_stream *tcp) { + connections = 0; + if (tcp->status != TCP_ERR_OK) netcat_loop_state = NETLOOP_FAIL; @@ -101,6 +104,10 @@ static int tcp_stream_on_create(struct tcp_stream *tcp) return 0; } + if (connections > 0) + return 0; + + connections++; netcat_loop_state = NETLOOP_FAIL; net_boot_file_size = 0; packets = 0; diff --git a/net/tcp.c b/net/tcp.c index 9fb80f9c2a8..c0045e32198 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -25,6 +25,7 @@ #include #include +#define TCP_STREAM_MAX (CONFIG_PROT_TCP_MAX_CONNS) #define TCP_SEND_RETRY 3 #define TCP_SEND_TIMEOUT 2000UL #define TCP_RX_INACTIVE_TIMEOUT 30000UL @@ -34,7 +35,7 @@ #define TCP_PACKET_OK 0 #define TCP_PACKET_DROP 1 -static struct tcp_stream tcp_stream; +static struct tcp_stream tcp_streams[TCP_STREAM_MAX]; static int (*tcp_stream_on_create)(struct tcp_stream *tcp); @@ -155,17 +156,24 @@ static void tcp_stream_destroy(struct tcp_stream *tcp) void tcp_init(void) { static int initialized; - struct tcp_stream *tcp = &tcp_stream; + struct tcp_stream *tcp; + int i; tcp_stream_on_create = NULL; if (!initialized) { initialized = 1; - memset(tcp, 0, sizeof(struct tcp_stream)); + for (i = 0; i < TCP_STREAM_MAX; i++) { + tcp = &tcp_streams[i]; + 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); + for (i = 0; i < TCP_STREAM_MAX; i++) { + tcp = &tcp_streams[i]; + tcp_stream_set_state(tcp, TCP_CLOSED); + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_destroy(tcp); + } } void tcp_stream_set_on_create_handler(int (*on_create)(struct tcp_stream *)) @@ -176,28 +184,40 @@ void tcp_stream_set_on_create_handler(int (*on_create)(struct tcp_stream *)) static struct tcp_stream *tcp_stream_add(struct in_addr rhost, u16 rport, u16 lport) { - struct tcp_stream *tcp = &tcp_stream; + int i; + struct tcp_stream *tcp; - if ((tcp_stream_on_create == NULL) || - (tcp->state != TCP_CLOSED)) + if (tcp_stream_on_create == NULL) return NULL; - tcp_stream_init(tcp, rhost, rport, lport); - if (!tcp_stream_on_create(tcp)) - return NULL; + for (i = 0; i < TCP_STREAM_MAX; i++) { + tcp = &tcp_streams[i]; + if (tcp->state != TCP_CLOSED) + continue; - return tcp; + tcp_stream_init(tcp, rhost, rport, lport); + if (!tcp_stream_on_create(tcp)) + return NULL; + + return tcp; + } + return NULL; } struct tcp_stream *tcp_stream_get(int is_new, struct in_addr rhost, u16 rport, u16 lport) { - struct tcp_stream *tcp = &tcp_stream; + int i; + struct tcp_stream *tcp; - if ((tcp->rhost.s_addr == rhost.s_addr) && - (tcp->rport == rport) && - (tcp->lport == lport)) - return tcp; + for (i = 0; i < TCP_STREAM_MAX; i++) { + tcp = &tcp_streams[i]; + + if ((tcp->rhost.s_addr == rhost.s_addr) && + (tcp->rport == rport) && + (tcp->lport == lport)) + return tcp; + } return is_new ? tcp_stream_add(rhost, rport, lport) : NULL; } @@ -390,12 +410,12 @@ static void tcp_stream_poll(struct tcp_stream *tcp, ulong time) void tcp_streams_poll(void) { - ulong time; - struct tcp_stream *tcp; + int i; + ulong time; time = get_timer(0); - tcp = &tcp_stream; - tcp_stream_poll(tcp, time); + for (i = 0; i < TCP_STREAM_MAX; i++) + tcp_stream_poll(&tcp_streams[i], time); } /** diff --git a/net/wget.c b/net/wget.c index c91ca0bbc90..500cb58d777 100644 --- a/net/wget.c +++ b/net/wget.c @@ -41,6 +41,7 @@ static int wget_tsize_num_hash; static char *image_url; static enum net_loop_state wget_loop_state; +static int connections; static ulong wget_load_size; @@ -119,6 +120,8 @@ static void show_block_marker(void) static void tcp_stream_on_closed(struct tcp_stream *tcp) { + connections = 0; + if (tcp->status != TCP_ERR_OK) wget_loop_state = NETLOOP_FAIL; @@ -223,6 +226,10 @@ static int tcp_stream_on_create(struct tcp_stream *tcp) (tcp->rport != server_port)) return 0; + if (connections > 0) + return 0; + + connections++; tcp->max_retry_count = WGET_RETRY_COUNT; tcp->initial_timeout = WGET_TIMEOUT; tcp->on_closed = tcp_stream_on_closed; From patchwork Thu Jun 27 11:39:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1953230 X-Patchwork-Delegate: pbrobinson@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=qrWFgZZD; 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 4W8xVy0cg3z20XB for ; Thu, 27 Jun 2024 21:42:02 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 325A2885E7; Thu, 27 Jun 2024 13:40:13 +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="qrWFgZZD"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 39D7D88630; Thu, 27 Jun 2024 13:40:10 +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 autolearn=no autolearn_force=no version=3.4.2 Received: from EUR03-AM7-obe.outbound.protection.outlook.com (mail-am7eur03on20700.outbound.protection.outlook.com [IPv6:2a01:111:f403:260e::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 63773885DB for ; Thu, 27 Jun 2024 13:40:08 +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=arcselector9901; d=microsoft.com; cv=none; b=k3logg0qFr/cw8B8zfdWkQzNkaYp/pULcnrMhDJr4664aGrQ2DxRZ2hSLR+iArYwGty0PdMZAjYJ/OFMXivgRA4SMbNz4QRYVsiAw9LoB4gX+iABZoCFSKK9rijCNn4vDXwM6KyUTDNtVS5aHqb1d2jSUwY++yJptRdRD9j3qxFTOMugTX2Omt3q32iu0ig4fJ3hR4Oa/Drz1qKdlGBLlMzNU50Iuk0Y64WYLyUUtfr3ZlnoTiT3W7fzaTlffk+19N3JPomPpw8XB46pYWgqpklPB2DPeHF2dYHa6zz7lsAITcwHxJ3juOVIlsTJx3He5e8mAOS2PR5T+DO2TYGnTA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=ySPOAhJHz0aPTCFI/sh45VZg7bEPrMP+QbrmglTv/ck=; b=C0dfYyHEodZQuuVdxDanisMX/UFQT9wR9iSSVTUBPOgWKygTVOQaMg/V4mIctnrTUmC1DZutqDNuVoM3gcwGusAYA5WYKac2K+4Cn+DekH5kvYQ1hrKkSthz3Nu7LU6P/nG3WRmGOekHpAcxKB0HzvwsK/qDiebSTVmXpDxHB0IplIHP6xv/Eo63A0lR+mpMCCRElZmOL4eqRWALbR7s9eu83vybSgQFU64Y4Cd1l9BK2/sDlC4VoAIBxvsrY/whtxkOX7xqQhzrqZAgP/lXkdYZ3/Ox6eT9lVVQ6jTieRs9lQ0zjkaDrPrFdVkyn04GkP0hm0Y5ddakBy97T9TWGQ== 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=ySPOAhJHz0aPTCFI/sh45VZg7bEPrMP+QbrmglTv/ck=; b=qrWFgZZDYd2OjMgsd5gQwlt/03gfphCmuYdpq/OfVFeaNz3orGYFFXOL1v3S8aXwfgwx3emwlY8cHcKWZjLZDA/sjpq8DYoZea7F2Hk5F4XJ+DGm/y4QGLGTZIAYNvf40XnKyEpte7qRoDKjm1cx2whDF53byh7UbimyalJJyOlWpWmZneecNmAlRZNzPWXc/3yE0Ysc4iN1gYnx5DLZbQEC6gbJ6XjKlRNsRlBdFX7ZPZllbY+XuiuuFjEi0Q6BLxorKRst5RpKfcNI+dgctZlfeasUu69ulRvo9CMJ6JKDorCFrINleKZBcV03Nmneis1caGsX06YImPCkYTS5Cg== 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 DU0PR08MB8640.eurprd08.prod.outlook.com (2603:10a6:10:400::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.32; Thu, 27 Jun 2024 11:40:05 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%5]) with mapi id 15.20.7698.025; Thu, 27 Jun 2024 11:40:05 +0000 From: Mikhail Kshevetskiy To: Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Francis Laniel , Abdellatif El Khlifi , Peter Robinson , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Marek Vasut , Baruch Siach , Siddharth Vadapalli , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH 12/12] net/tcp: define a fallback value for rcv_wnd size Date: Thu, 27 Jun 2024 14:39:39 +0300 Message-ID: <20240627113939.100620-12-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> References: <20240627113939.100620-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV3PEPF00002BB3.SWEP280.PROD.OUTLOOK.COM (2603:10a6:144:1:0:6:0:21) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB8640:EE_ X-MS-Office365-Filtering-Correlation-Id: b634e509-6e60-4844-3296-08dc969de366 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|366016|52116014|376014|7416014|1800799024|921020|38350700014; X-Microsoft-Antispam-Message-Info: 6ShilAwCaQFkq/czfETtbm99YTBg/E7erfWe544mwODzazykuJ6k5I5dNQKJ1TVuBOLro/qBGXYMUFDtfxaVFYGyPKw68fgVhz0SukAoJUMJ5QnrHrUGdCkya7d8EUuPqCPKAzQrHybTwS4JU2tblHesp07y17579SlVuuvI8HwN3wx+OUCTVTfwT0j8hE7ySi6NJ8FdiO5hQ2ZWI2a+CW4oS6FbFHG7CnQyXfRltqHVDrDr5wVKdNLxyXh6fHIuzHK/0xCx5eR5NjXjTPv1sT9wAdXhCM5K+7cSWZji7LdwlotBRiTfok89lCwwYrINp6Ae4LPRTi51mQ7Tue4CwAQ77g/PehOZoYRToECnX8kl2Ww7iOtsm/W4WJh3S7+ib+TLXpal4Hjjis3cmCuoGf8o5y4Ug2L7wWTTagqWQfnhTHobDaM7FiK0g7ouBvhz9aOhR+VC8+3iEgRhX5cnVD0bk4xxYTNC/B7Y63ACXzC7g60pVdwcsQE3BdaPGvWmSvXW/lY8TRsjDbs/Gfi5AcwXoZtIrYlLe67kmAN8BwKWTlyRw2yUZyTs6M9TZBy/S29q5qw08VZYqU+g6omNUxvDRe4vni9bhRZ3mC4aAYf/ngwZuZed6sIOselLhc2q6IrQ8M1qgFxw71RQHTnnU50uBjllrRIgJDvofX9ev7RbzgByfIOkwhuMx24YlV/UbFi14c8u1HgVREa0Hurntvf/FOX8RIjTmTyT+sfbR18fjRe0lHjRMGKogAuN22u3HMpKLSmZF5CU5GdJqUKjcXXe7+AT9lvQn2fVWyBFfKq3qI4/4Fpy1QWu3lXEIOgV822+Hnmu1PXDmsj8kXIM2AK1pWCqe7mA01w6ZzgGpRovP3p3ysCZR/2dXclf/cDWHnpdw/UtTqBDxHewnF6pVTPXfxOsHIHekUS0M1rPZPZru+eIWkE62G25EvJ1cKB15J+nlx/pxstFKXKVI0cYA7AezKJPP3jL/DtMKn3Mm8DMKA8szmrumJ/CEL4+u4Mo8BI22grhSmWogEKIk4WcOQeuSzhS2MkM2M9dtNLkSsSeFQJiK5LJAuAm66jZXgG5fuK5CIzqWyrf8v67F8Aicj0mm0qtvAe7Ro5Vk78bfbxmHorsmhZ9lE0SfWEDwIzaB2av8XVAidYjXIrwHnOAax0YLF6vfba0FjefhQpoH2h05PsmU9OG/X+KrGNVrmfbbyoFWsstBucShFmlKDpsujJDIEqCPm6mxG0W7t0/rO7DusGAJDDUEzR1KBKMtHBt3KNBaBTJHWnyu8Zedrk5hDdus8PLv7bIMeMlk6v39pOyDU4irCOklLavAXQ5FEIw68HwFBW2S1HyMVfeROJX10SYqDcj2vGY7JEWZz9fImfl8mwA8cs2bXq3Nbq/5ssaLknNi3u82o5O268QbChAUcMhgiOU0KFRNOMsrGVFR6M= 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)(52116014)(376014)(7416014)(1800799024)(921020)(38350700014); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: aB5hg9V5gYoQjI9ijWj0JuTu1B6PHDWPxAlU4KArq/6vUy/CJMh3B/2HKGPnMIcoKztJat+IaLDMXj1W9CWxsM/ohlUhG+GZzCx1wyJQnTRrA/czHpmqgh89voJqG7kzOQ9qjbGQY3srZ7VfIqJJhjP2nZQ018dlBnHhjnR3l+Tseb1vgUJLQFN5H+JGEeH0Lm4ogtxQlrwhYEHgk16ddhmymzuYbhLmCzlMVqU45jbKjoUX9D80ElniyVDp0AOfCJcEkrOS0t7Dd8LCojSVLQAAtzGRQ78dU2nwzyA/5+OiseuYQ/iFXe+CqCPWBYYx9KdpKrYYdpQclmZBl38EpBAzBSyOJTZ3B+zhhHAR5OCFFFrk6DbHDVYOm4R1wQm7VW4M+k7loJu/8UgeamUrvmN0snr4k2G0UWWa2Mi2Y4efpeY1/z+0PkGm7CU/HdHkvaQqcIdgJxA8CWsX0+xACv8HvmbDOj1LyjzhhvDzOfg/Af3V0WptyScVwRKQcxBYuFYrjs9Qn5oDIiwwbxhb54dlz9wE77nBVqvuGjmbEKoTAhB0UEXVvvhLFr5ei2HrQlDEHMV1fNkhw+dxbxvphOG5rYQBDyYAH+9TZDJs+DVc/0JBHb1u/hMbxJL900jwv2+zFcINNgqAXo6v6cG+C9ys5ndSxY6GbTzbpunyBQ0MR7XX0OhYPNw67jdgJobgkaVETlobCHUuu4V7WS1Fci5AUkgpFb/y1iB+erhDXOEenLQPfz6vVwnYm6dGaBk2t7c68hshaqMFiMg0aqOhPO6S4j01kwIx2Y0/GVAKeRkFR8Kk0oPDF4N0dVId4M1lsMa/mr4EHzJbUc87hihc2unq/21HrLvyWE7p5q5XqQ8UGzfEM/tJ2ZfQK7AwtDOt8Bhi8X+5Fc+hzRdtS5SLyQpWrTIGKrV6e0RpM3Oa7bZrVtmYk5EkfURXA6500HV9TKSq/Yv+fnvJlj1VLeMms49VHDTzCQ/2k4Z3tVk88DpvUeooH9BuU03ig1GzVuasGY+bNVmhO9sJ6OvxOVNl5XhT8Pqs2PnI5ZVfX/8zSTz1xfp7E6L+gl6J+inkxGPscYpcFpmBd8DmWFPg8tqEWbuP/E8ioAmX2XAYfamuub+XhbytDfTr1hHoYYTKq0+n/7BJAGH5/Vwqe4iAZGO9q6Lwe6VqOPlz4lXHcpwbJkaTti9PN52OYbGsEGsNO0YbAF7K7iBkfUAQ77h2RkgQMxg74J4FRCaliuCMYtpFVUTEUwFJESWa9o29w0cCm6YdmkbWvEdcZ1bMJWnjSppuvWQa75lyOmuXbCt7b5aM9a0yodAeaw31aE/7l+jFhrMt/mWwXpx7y/ziMqok38M823IAiMrDSmNi180ZQmK3xeoCW3aTHd2U23xVdBFkc1THN2/Ttjtm61Hma5L8PunDdHqyMRCWdaetavKfQZbJqXL6yTnXQ6P3UArUH8NwDPqE30qRMVlIzXq4yUf0sCFqt5DXYXSaag4WUUe3vGRA79xFeoBOEahplmarBpwe7F/R62sZ3wTuvMYgKqADaUO34PIoWsEnkTxnH/97bn17XQVO8mZDpITppT2y+8HxoJvwkaQh8C0wYQRx3FkcWtQ5zoK8/QGHBZnaHjCD2/EtIrc= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: b634e509-6e60-4844-3296-08dc969de366 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jun 2024 11:40:05.1704 (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: lzzj2VxEmybrODtySXzM5iq0DAymythSfwzd4INb1/NBa2wMStmBCINQnMI+DEIOvduQTBIBrOEenFsRBuxlDU0e0gVBITVH+LPt17ZNJhI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB8640 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. Avod it by setting a reasonable fallback value. Signed-off-by: Mikhail Kshevetskiy --- net/tcp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/tcp.c b/net/tcp.c index c0045e32198..3f12c71e1f7 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -30,7 +30,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