From patchwork Sat Sep 21 03:43:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988101 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=dcKs6XUv; 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) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X9ZrJ5z7xz1y1t for ; Sat, 21 Sep 2024 13:44:32 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id C200488703; Sat, 21 Sep 2024 05:44: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="dcKs6XUv"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 3CC34887FA; Sat, 21 Sep 2024 05:44:09 +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-am7eur03on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:260e::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 55E2D884DB for ; Sat, 21 Sep 2024 05:44: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=arcselector10001; d=microsoft.com; cv=none; b=yvaVis1j9AOeB3nTvLxtlqHgo+GmwTaLeZeJVXH3RJATqGZlV6BINyCSTboZ9aLZcn6yFO8SkBdxvbhdixwC0Krs0ytQnKfGiRv9hDshpGXx1oP6hzY6/Wvnf8tA4y+yMRzfDpj8oxLbLOedosfcqGodxfpuSTDZlua9Bxu+zmPBuPT9lY93wO7C7N5AcRY5iwU2OizRFyk5hjnYSuI90/JGIDsEqshs5eyQVfljn/TXtOjKIe6IbCjni6NUC/GTy4H2ilS69siHuvXHgBy/JAOT6xj1GGheQYTaPz/FauaZ6xhg80Ebk6O4xF2sj4sdG8wyJWoxv+en/H1ijvvrcg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=BEz99YBS3mgQpsbqTk31psHOSp1vBUbPdtOGEPpO9Vk=; b=g1VlX2GFr2uyOEepnJTJyC5VLObcrT6zT6lewzmC6QGSAIXcbFfvaGgqLSYcDc6SoxicnmrKXx2cC8lHlYu3oT3P0oz1S1pQYu6uwOYEjov36/6xon8NyJsQ5WfKnI+4PAzZ3KcQsvUV5Fo9K4IUhRvtAk8HDsauU5VsxE2aQAE+mXJm2NLiF5G62/Tyts1UlIwzIklEMB6+z5pAjakCR0h3gKrt3p/x3yHOfPE917/v7WhD+vDcR7zxBQ/rWJ6NNuC70Lr42CTh0xJVsoq51+7G7RJ5vSCCyrWnJSUNFmRMi+hb5jQUcmiZ2ruP1Vt6KluXPK0T2IRnsNXv/yCyDQ== 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=BEz99YBS3mgQpsbqTk31psHOSp1vBUbPdtOGEPpO9Vk=; b=dcKs6XUv67ZwTsgaLntmvu2nsuyzUNTzCHz2NkU1E7xDwv06N3RUnIAmsF2rVEKLePNctw4cpRQtYGxKZV5wSUtABNZgZBEATJdj2Gbf/ZGqmlZpLqyAiN/cCey3KJ/MQHGejIFeETX5MmgLHbbGmtCcnkwtX75ectemYSwAPU3A9fyxkrai5PCmTwaDr6bWY6i4tSNf664jOANAF0K4aXj+MluYafsXAAgDWWBeTZ+pi0sExn2i3noml4/YRM4BFmH1BgWfY5dYyinO8YdEpu/t2EtxJOCVbpiTLbOylPtAuzow5X8SVhpjbwkHUyC39WQF2DmxUzviEk8ZqcfkMA== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44: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%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:03 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 01/13] net/tcp: fix TCP options processing Date: Sat, 21 Sep 2024 06:43:41 +0300 Message-ID: <20240921034353.1298452-2-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: 37c747d5-4e67-409a-cba6-08dcd9efa2de X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: CYhCPJYZEDOq3nQPnWPlPvE8mu638QsTQzH8UlVYUrdHyNmbALi5uL2nQt6eViCnnJYTYU1fG1cWjx/jIyrKIv020Bw33cul/kYsKDlQR5O2va29F4qmZUJoGceI5SxoTbbZkE8CHbcwOEuxmkCZ8AiLwM8qIFGNRdOftEblSSKWcbN1P39TzpMetANO3cU92l+jxJR2nZsG3PDBupgaNg/9VXXFdnhDPNn1kh8YAvTse6ZKXPdBfnjVmKpCta21qz5YQae+c6XSO7y8kBerW9TvigEVWT0UStWTGNMs47YF4yQ+BD7JKwmiUy6ohT88ZAgH3xC7LQoZpHB1NPhiyo3NT3PPftMMLXGLWr0BukrtGVIard3z/i3eHU7DfPPFKupRIIhlcVqe+vhPiILpYHP48IXCj7Ov2+SqLcwBnGeFEBO+ek3yD/7V8ectII5JIKBIGDepvdsgEf6C+C3NEoSIRSmDIQpjJijImcUEdLmTueBEPEUpQGFroVpP9vv/w8l/r3bR4qCo4iMR5071rsdil0KM79yeXJeGKv3595agDDIp8BV/UFIDpZ5OxoQgG2jdKnsn3S7v/Y57nJZgs0tUvGwJTCk+rQ4FRYMmCf8jueYxDY9HeJzthBZPMGyDHm74iYgtcoX/IuNGSOe0UmrQUvGXlRoC2+/6T9Sxr7K+SsANiKkTRftdRW20ZqscXZeuA+uImlfzLgNSOg1U3ls8GbbieCanatrlsVuuOVdrBrY6WuzM2mvIMkWCq0+fjdSeNcYRqLdl0+jDcmaNSThjfU+PLJhay78OMZMCQWTb+7ubwMRRFR+Fcjn4swgKV0vwul/jDnSQxsP/Bm77tTnB2jTBwi1DU1mDD30JOGHzzhhWQrjXXEelykCfpHPz0JaXCKdx+abcWvA9JQfCSGWqam4Y7G/420nWmY/RvAYsK6XtY7I5lFtHyq8QbBRqqjqLoWRelMtUq8FxltUOPITvDVGW4aR1JkdoY0lMv5ryFjKb5wopbDPJR0vnwYL3Lp2asaloueJdT+JysGDKnjWtXjOx60doRCOT5KnD5bOsHHA4MS+hOsD5glv664i9YwOTHyDIFAd2WJynfLOE2/F6CjG7d2mDb37NPeeWR1bZST5CXdV0awvuQgXDpj53GmgVKrCQgQYzCGNnDxvqiDV80/T4jiOymlmY5JqS7ghMSYas2sHhpbJIJm0a5ImEdpch1YKQyWX48P92Dqvb5Ko+VPy1lwmrl8CEgozTvz6ExJEKpAelKbINZ0JcOdL4eadx1bSVtC8uUHP17jXUQgh1SGJbIX/tb2FBP1sVEUX7IwTXjyuVIFJi2jy5m09/l228vROKLuDhIzeu1Rr5b9wEhLPX4iCkpZFmCNghYzE= 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: +98Yzoz0GqMO9ZB0AIuLHpKxbI7ylbjyE/j3uiCrk+RN7ewhP1uB3+bhrB1SkOfS/JXFFybTU8aSeGxKONPDfskBfMIdoT8z2xtDcurQ5yZCMCTQ/JFbUlV4I1U+ylF+Th21Q8wHQO9kz2gIQRQVPABEjyOomGD8dHtil6GWuElgUmFp2O/LrrpDa9z7cXVKojccoYA2ux6lO7UvjXqmnculMo8jtzIEh8fM7d9QxgEGpvlOG1A+P/VrIt8FIInhryrFI3YqWiU2Gs0LtIo93DUv5J9Zl8y7fHySk7VnIwor1FTpnW7VYELZkFvOp6NnXYAOVKNx89651UNFbeP8XomrEkanfNNwefo6MjT/PjmQXyRf50Vl+dsLUnBvgqaCxZi0Pko+IfGOt2IufGLRwjku+Ro718XDosAb3YhT6DWEuMFFgcc4we+SCsiqiC7p5da1IGWpZ/SQpm8y7r3yTg+9O+GP819r2c+kOYhwErGIWWNxa5G7HrZsTuF/usf1rThVx2ckzwUn8MwtDq9VVVX6Drw0XijbgRGWyQUmfg7E9rF2oHZBGf+ZpMs1T28eAZs8Pi69q0mKOPb80xYIual0BYQfuMOuuzWlxEQAsjXzrwTZHSjrm0df61T2VFWs43OnFYtAFejjMZEYk0dX5Y6AoPuF1QLqFVWOERzVQFOeDCW6Bb7OVu0v8xWvSCkCdCvcQHOGAljSSS+uO2B0kS5oO0Miom8TTV0R2Nuhu0YmY//kw33YwiKm/d2HbUmAVyhUHn0TrcnvoeApFm5ypsi5dz2VUo62TKi8MAM3loCi7re1jum0KUAs4+QxCZk2ZuHjkBP+/Pzqksa0I4XRa5xFQtVwj7neK6c6eSIF/OgZBuVyyGrprgiwrkTlBSd4DD9cqehtZIeAGTDTIBMN3UxBQA5AkqjCw4zv6Do/vxtr8fHToGEek52Ia4bqzzsn5neMZ6WYFmFrYCGrVVcnj4CPtzaQghpGuKqExWKqjvFoSgr9o0HKlAV0eJLCBtsbPDQrvdEx2e4ThS+6l71dsISdaRM85Z8Qi2NXYrJrencJsDEKRnwodvKH98Bc/O1vVpLFoL6JpzyX/bZbXZMm5R94ra+knGD33R7Q+RCVE+Vf7wKCLzTqHr1vAwWN1kGVT917m0Q6W0/QkMNnGct//pKC7V/iRrGbFUGMi7c8KZkxs8dXKfd7bSOe6sPmusPr/0dP8pJ7XKzjT5TUBWlGEa+oJ+y5alxD8db9u+gsGUPvP41R52lExv4EIxZakxF6j54P9TTlqymoSvMCBnu7xHfzNCTXDoZg6NLvaVch/cIqg3zzqgyJJvWr+TX5hJd7NbxHIgZ1duJn4NQJ3wueMQD0kWa9zoZelIz/67WFo+VBxBZBi7QnnhGIsM8qUW4twinJIpUyKFEtRVAZeCs/01XT7TZKCPpJXocVrRBy0WSkekumsmjqyWuQ3TsPjxo3FHImwgz39FqF6DGSKgQ09wfCT4dTN/+D3eQGn9FpLFYuolrie4Ti3IpXNbTsT8HR7J/GBfMYHct6udZZ01FLTZyVePN9aMXDxU7a4uzqBsGSnUjTji2C5BR25zb892UqKflZrP3+URK6XjOayHR5+8Bl8H9sahC9NwmK/KDcb8k= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 37c747d5-4e67-409a-cba6-08dcd9efa2de X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:03.4555 (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: L6myVi2t3VgDS0+tWSGhNZAduRDlwckx6LE2e/HNd3uTtsXxVEUfgobypJ6q8LSq9o2u+83BCE4+HnIswvyLx53nRJWM8pbo8VfI9oi9h3s= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Current TCP code may miss an option if TCP_O_NOP option was used before it for proper aligning. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- net/tcp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/tcp.c b/net/tcp.c index b0cc8a1fe3e..3e3118de450 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -475,7 +475,7 @@ void tcp_parse_options(uchar *o, int o_len) * NOPs are options with a zero length, and thus are special. * All other options have length fields. */ - for (p = o; p < (o + o_len); p = p + p[1]) { + for (p = o; p < (o + o_len); ) { if (!p[1]) return; /* Finished processing options */ @@ -490,12 +490,14 @@ void tcp_parse_options(uchar *o, int o_len) case TCP_O_TS: tsopt = (struct tcp_t_opt *)p; rmt_timestamp = tsopt->t_snd; - return; + break; } /* Process optional NOPs */ if (p[0] == TCP_O_NOP) p++; + else + p += p[1]; } } From patchwork Sat Sep 21 03:43:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988102 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=Cjn6HlsM; 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 4X9ZrM6P1zz1y1t for ; Sat, 21 Sep 2024 13:44:35 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 3B44A8891B; Sat, 21 Sep 2024 05:44:11 +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="Cjn6HlsM"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9B42388581; Sat, 21 Sep 2024 05:44:09 +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 5308E8863E for ; Sat, 21 Sep 2024 05:44:06 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=fKiK73hP2nLIDi5S5cz7QnHgSydm5UJJg7mnC/YpZDrgJ6UmkAJyxd1TDEA0JztjisoWTqh8balVOJ/jTFmgf/Ry4iX1MMhDpsmPbbhqTxbdfzmgwNGwMUSVVzdHj+fOpPflK5BClizqz/CjKDiU6x+qdLhv4zuJmNiCyOTkCHsvGlKEkngrRqWovoPb3ddWeJRVeSEzWugqCQgS7mmmnz3h5rH7QVcxurRIiA5F1SD4KKiGzixtvX2K7YW4Cyu+yNLiBV5ac1+wzQfAhD6Qz90Wc4rbA8F+0YO4eSiwYVuORLDFuyiPhLYUitLu1NXJmk7iMajd5Acrk7lAUGSK3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RfJdq+jM1FJcu+qcheP0L7cOWIJ0srHW56AvYyehGWw=; b=gHxFb9IpHPuFGGCFMB2gDOZb7i+bvulPPzj/SOEvT8Vve1OiNot5O9lLBebI2wS3zAGhSwGr0SrQlKTHHwZ16hdcTRAZMTDnDjxyr0fSpTg/c1NwpiGsKaXRQOXthirHj/6RqJU4k9NLzm5S6But+/mRyPeveuB1TpKyAK/WWufv7MMW71KmaV3D9gEif/00W2oh+iFBt/kgX+Hg8QvuQoq3cjqcOtWyX1JX82HU7VjmIzbAfk/eDj05qLst50zRfoTmkuoSrb0ZVIHZ3iSEUEOO8SNWswPoiS5i8iBmJYwHb8W1z3UpvxKu9IiGrB2tkmmbFr5hfFoOZy7vKCkT4A== 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=RfJdq+jM1FJcu+qcheP0L7cOWIJ0srHW56AvYyehGWw=; b=Cjn6HlsM1K1Xu0i3Vw3w91cvewV+eD4t9y7KyB8wKODq1P/GHu2QTZN0kDSBRgTwldYpiXu0c7Y6xuojEkvLqTz59EO3XNmDUm9OsxdNNoigIEvY82xR9SalbdOsOT1QVPSPuXDxisoSIvGmm1u7XfcC/QenIBtVR9jCXR4F/b7sLmT/z/O8QDkSw9W0P0Zuj5uFBQm9+PxNTwJ4XjoMWePE7zPrbCrD7iwEeuFA29hgDZqboHA9U2d3BybvVMnuLtHSbIWp7eO5moA0Gyuce2nQLa5nCltyAWYvoZQvZZVxVOUc8q6OCpuBjWzQj/pN17kjzS0veAvg43EmETSECQ== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44: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%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:04 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 02/13] net/tcp: fix selective acknowledge Date: Sat, 21 Sep 2024 06:43:42 +0300 Message-ID: <20240921034353.1298452-3-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: caf43a9e-3c1f-4af8-754e-08dcd9efa3bf X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: cZgz2Zue+rwvMee8nFE1E33lPz99IhneAjz9Jg+zwBRB6UyBwIBsh+BUykEP8V/KB1FNqvDquFtnJd/Kk9Lrx8Kmn6TvCvwKkTDyhHC/A3Qjw8dOCOfED1qu4juAsp+hgDNWVLdy6SP6KZHko89iWvfpqLnRfZOCo0CkGvvuhjakGbeIJMz5jKDlgd8Q7np09F1NbkkMMa+tHufw25ydpZvOYN4SD1KbIWK5fmyintK9yzQ4/zi5azxc9AvGekeyo+vfXcWVZOpYJjkGqAMrRI8dKWB9Q7LSql6oWttT1TN2LBff+NOirEjYmV6Gae7ftKxwM60JsgB+4vcfG+OlG6+ddVj5XFjXuXgZpVpYZ4ljfpOXXx/jfXDecY82eLvh3M+r1GDS4mCbmi0a2yOGU90/HyIraqfWrKPEWRQk3e/vslHkeB6Xt3p2BAA8xb4pHwmUhtJVyCi22bjA0VArxVDuY9gOSZcmd9l9aJ2LEjPe02u6Q79DpoPV6y2AGo8QcfcMO8DAex9874hSqPuQFGhfnB+3dpsU5Az7jhBWdPHcXjdPsrePh6HSEPvc8fDtUo/9265zaq88+4TsHFtcGjX6HtnM6wBr6M17C5pgmUwm968pcRPTyW0tpM2Vnb4g4ASTxpSE/g0l/BfvObyLf+JoPiW/UhYc5czeBpJgOVJXDaKg8QcjyU8pgiccAJkNG7zjosl3nnGSmr8AmU1T+u2CPVlF//o5ZV2fauaAnJLa2SIogDwRyILAIpxifebY5LmTqw53jGEYdyFlGsMMjospn6e3XK9nliJZIG5vdOfpBkbW/UD/7Yio1qA5ma+fPktVVRgzVm3WL6pgeLBiJiOaFWSy9zY/SYxU5y4jgd6fhwjBHNjQKBkofpe4O+qf2bXEPnPOSqWcrfr2j3Wo4xCdj/sn+JtW6tKo6JJkr5XDNNBr3IrmmGjl52ZiP5c/8UhBnMj+8BaMNp40VJv3C+oEOQ1q3LMl0FCQpJKtTFucbFRsjKgPjtrV6H3GaI6H978ySYEV/oxGjhH3m/NIzUrIxATIZVSJ0gUhtZAIJ+cdVzCfRa7Ze/oz1z/EKgIoYXgoJ5GG225miA3f6XS4vwOKm/UVdh6F3CE24qK+bY2pygrz08rusXmhLZM97Rv6EGkj0yJreVk2AFHLrAAYukurOLkKwz/WN/Dep11m82QsnK5nnaSt9SADfuUdot2zcSq0G4M36jIPizKdCaSYrCdY1dCSYSAvWBOsJP35wY+i8b+a3U6jHMw6PJZOp7nq1BmBla5JX3tMc1ISXhXUbYjVAU+FuK8mGjO4fjd/jgflBG+810I/pmKDHLULmFxxd+eZo81CdlGM9q37eGB7mk6PEtwnke9+zYd5uGbwdN4= 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: Yi9A+osCzQfKAoGTlZxq4qUILXj07cUNmsfqfPHo+sNThNlnL49Xl+AgF/myrANTJCBJKWFqtmRevp52OEDhD6OQgMxHrg9xI28BuEAbZ6jR6BMtvZ/l6ZRscTsWUgXAuVLqqDtb8p0BxhlXmmxHTY/YzM36FOVY70IHdzzKopdBYIALJofHoVlm4pGH9UJoEO0TZf9awrWxgyhe3ugi063UcrG3jPglo9MBDJq8hS6zYSgaa93GYtG4nvMKGtGo/Hyzambh2QRsq45Y6C4zYSAsAVJ8qTpNx0FxpnpCxp6KRt/ALr+TW2pmam1Nw0b2reQSKuSjdl1YUbltTFB0nQtaMO8diD0odHnF23uLEcEybJzKoJnuMrVs3Fm3tKeiV2FtsTjX1gFgqAtowpJTtTxoUTdQn8tZzyvX5tAkTgjtYb4zAo7rukewshrYlweobg8a0jpcu9Ub/nULSG1smXhXiW8vkYaRYdeU8gWzpuhI4QxJGnp04kCQaTj+pu+hknfwgPJdXt2jCITrpoJr+0KfbWWZ/cjBmumld8rCZosuIsjTfih+YQbWY5xmK//fSKgh7jctJiA04FTfPNB2QYQxDk0m0rlSGo1iwdE1aWBWnY95V8jJEEGqxaQeoSiFX7hIY4Nlo/PRHKfT537MLT6o1hEqR5tlO4vuAmZ4xo1fQyDbiMKyTYzHcKq4afu6Xd0jdElRlNPCQv41aMPn52lPZdIdt8Qm7PoVtcx5fK8mYqSTRwvTvs8LCl1VsG+R2yBuLAhIDZh7ss8H2GY/Bx0mD8kp9JudsoTZSyUHQEmYA6RD88Wv/n7WFpskn1VNl6/82usgUrmD0ixnta2xaKaeIFlDZ3X6MgPT7z/xHIWo6nC9cVpIsB7HB/e5GXTet/siSYPaf4vD0lOsH7HP84SfD0m9fnDTj8FEP36t9Ge0Uz2MXQiytiaiSoa3wP7BoNNViuVT2EAdoAvolhUk8kBiAJdBKW+CEZFe+SgWUzhoahqL1fqMg77DqHQrRcBGBETogzUnTCVE5cuf1F9BQydeEqm8C91Go8usfiywJUcyBevS/8j9DKjLG0HUYd8ezdLnhrV3bl646C/IuFgkjhs6d9ISCnMeqZoBXzpmAWfEswqqokAUa36CfrN87q7s9wIuZHb5wxEBr0+uHEHkAbkrzUJbT0VXCphwdBg5SKVRvN9hJbS8B3UTk9ow5dGMPWPSDGgZ4AoK3VtFjptg+DfdMWAKj0ii5H4sj/Zeu3mAFUnCwoZS4QzWDtvYGo2FR4Fl2jJjTCQAA/cfqHIZPPSdW/HkO6khdp6WX+TLzo5Liw5eaody81/4tU+vdEM977lh3Xyj7mf1tC0iXIe/Be7qybNJ2foPsf1726mrRTAt2wkX/nEs/c3BzvXFx16f60u7nunM/mykbDkO082tZ+2DWCbt40Qk9SSMvR8GBvCHVCBvQLorJ1LxDDUHjGu8GcYat6Oz+XaZWA7ykncHlnED3aMX1pRyeoK598xGVjbrqHEiiMDPvfFQPvfQFoHSjIoJ6RTJghGS+HRp1M7dVhkA7RKhYlOK2L+oydEXo4ikM2OyrpvPH2i1noxkKNQ8aJcIuLyFOTbKUSa10eYRu73xI63m50V6/XMSCMmxQpQ= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: caf43a9e-3c1f-4af8-754e-08dcd9efa3bf X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:04.8848 (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: llB7Ind0IuwzzR2JwOQtnVHAqScMeAZsORdEHEUlCLoDmW6ZdkHnJwIxHZJOuu4cxyUFG1+7n8GhtPxVr+zHa6KjRXK6HRZBS/38nUIIQhE= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Current code assume that all (except last) packets are of the same size. This is definitely wrong. Replace SACK code with a new one, that does not rely on this assumption. Also this code uses less memory. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- net/tcp.c | 200 +++++++++++++++++++++++------------------------------- 1 file changed, 86 insertions(+), 114 deletions(-) diff --git a/net/tcp.c b/net/tcp.c index 3e3118de450..724536cb352 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -38,21 +38,6 @@ static u32 tcp_ack_edge; static int tcp_activity_count; -/* - * Search for TCP_SACK and review the comments before the code section - * TCP_SACK is the number of packets at the front of the stream - */ - -enum pkt_state {PKT, NOPKT}; -struct sack_r { - struct sack_edges se; - enum pkt_state st; -}; - -static struct sack_r edge_a[TCP_SACK]; -static unsigned int sack_idx; -static unsigned int prev_len; - /* * TCP lengths are stored as a rounded up number of 32 bit words. * Add 3 to length round up, rounded, then divided into the @@ -69,6 +54,11 @@ static enum tcp_state current_tcp_state; /* Current TCP RX packet handler */ static rxhand_tcp *tcp_packet_handler; +static inline s32 tcp_seq_cmp(u32 a, u32 b) +{ + return (s32)(a - b); +} + /** * tcp_get_tcp_state() - get current TCP state * @@ -267,6 +257,7 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, action = TCP_FIN; current_tcp_state = TCP_FIN_WAIT_1; } else { + tcp_lost.len = TCP_OPT_LEN_2; current_tcp_state = TCP_SYN_SENT; } break; @@ -353,6 +344,20 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, return pkt_hdr_len; } +static void tcp_update_ack_edge(void) +{ + if (tcp_seq_cmp(tcp_ack_edge, tcp_lost.hill[0].l) >= 0) { + tcp_ack_edge = tcp_lost.hill[0].r; + + memmove(&tcp_lost.hill[0], &tcp_lost.hill[1], + (TCP_SACK_HILLS - 1) * sizeof(struct sack_edges)); + + tcp_lost.len -= TCP_OPT_LEN_8; + tcp_lost.hill[TCP_SACK_HILLS - 1].l = TCP_O_NOP; + tcp_lost.hill[TCP_SACK_HILLS - 1].r = TCP_O_NOP; + } +} + /** * tcp_hole() - Selective Acknowledgment (Essential for fast stream transfer) * @tcp_seq_num: TCP sequence start number @@ -360,106 +365,79 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, */ void tcp_hole(u32 tcp_seq_num, u32 len) { - u32 idx_sack, sack_in; - u32 sack_end = TCP_SACK - 1; - u32 hill = 0; - enum pkt_state expect = PKT; - u32 seq = tcp_seq_num - tcp_seq_init; - u32 hol_l = tcp_ack_edge - tcp_seq_init; - u32 hol_r = 0; - - /* Place new seq number in correct place in receive array */ - if (prev_len == 0) - prev_len = len; - - idx_sack = sack_idx + ((tcp_seq_num - tcp_ack_edge) / prev_len); - if (idx_sack < TCP_SACK) { - edge_a[idx_sack].se.l = tcp_seq_num; - edge_a[idx_sack].se.r = tcp_seq_num + len; - edge_a[idx_sack].st = PKT; + int i, j, cnt, cnt_move; - /* - * The fin (last) packet is not the same length as data - * packets, and if it's length is recorded and used for - * array index calculation, calculation breaks. - */ - if (prev_len < len) - prev_len = len; - } + cnt = (tcp_lost.len - TCP_OPT_LEN_2) / TCP_OPT_LEN_8; + for (i = 0; i < cnt; i++) { + if (tcp_seq_cmp(tcp_lost.hill[i].r, tcp_seq_num) < 0) + continue; + if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num + len) > 0) + break; - debug_cond(DEBUG_DEV_PKT, - "TCP 1 seq %d, edg %d, len %d, sack_idx %d, sack_end %d\n", - seq, hol_l, len, sack_idx, sack_end); + if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num) > 0) + tcp_lost.hill[i].l = tcp_seq_num; + if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num) < 0) { + len += tcp_seq_num - tcp_lost.hill[i].l; + tcp_seq_num = tcp_lost.hill[i].l; + } + if (tcp_seq_cmp(tcp_lost.hill[i].r, tcp_seq_num + len) >= 0) { + tcp_update_ack_edge(); + return; + } - /* Right edge of contiguous stream, is the left edge of first hill */ - hol_l = tcp_seq_num - tcp_seq_init; - hol_r = hol_l + len; + /* check overlapping with next hills */ + cnt_move = 0; + tcp_lost.hill[i].r = tcp_seq_num + len; + for (j = i + 1; j < cnt; j++) { + if (tcp_seq_cmp(tcp_lost.hill[j].l, tcp_lost.hill[i].r) > 0) + break; - if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) - tcp_lost.len = TCP_OPT_LEN_2; + tcp_lost.hill[i].r = tcp_lost.hill[j].r; + cnt_move++; + } - debug_cond(DEBUG_DEV_PKT, - "TCP 1 in %d, seq %d, pkt_l %d, pkt_r %d, sack_idx %d, sack_end %d\n", - idx_sack, seq, hol_l, hol_r, sack_idx, sack_end); - - for (sack_in = sack_idx; sack_in < sack_end && hill < TCP_SACK_HILLS; - sack_in++) { - switch (expect) { - case NOPKT: - switch (edge_a[sack_in].st) { - case NOPKT: - debug_cond(DEBUG_INT_STATE, "N"); - break; - case PKT: - debug_cond(DEBUG_INT_STATE, "n"); - if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) { - tcp_lost.hill[hill].l = - edge_a[sack_in].se.l; - tcp_lost.hill[hill].r = - edge_a[sack_in].se.r; - } - expect = PKT; - break; - } - break; - case PKT: - switch (edge_a[sack_in].st) { - case NOPKT: - debug_cond(DEBUG_INT_STATE, "p"); - if (sack_in > sack_idx && - hill < TCP_SACK_HILLS) { - hill++; - if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) - tcp_lost.len += TCP_OPT_LEN_8; - } - expect = NOPKT; - break; - case PKT: - debug_cond(DEBUG_INT_STATE, "P"); - - if (tcp_ack_edge == edge_a[sack_in].se.l) { - tcp_ack_edge = edge_a[sack_in].se.r; - edge_a[sack_in].st = NOPKT; - sack_idx++; - } else { - if (IS_ENABLED(CONFIG_PROT_TCP_SACK) && - hill < TCP_SACK_HILLS) - tcp_lost.hill[hill].r = - edge_a[sack_in].se.r; - if (IS_ENABLED(CONFIG_PROT_TCP_SACK) && - sack_in == sack_end - 1) - tcp_lost.hill[hill].r = - edge_a[sack_in].se.r; - } - break; + if (cnt_move > 0) { + if (cnt > i + cnt_move + 1) + memmove(&tcp_lost.hill[i + 1], + &tcp_lost.hill[i + cnt_move + 1], + cnt_move * sizeof(struct sack_edges)); + + cnt -= cnt_move; + tcp_lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; + for (j = cnt; j < TCP_SACK_HILLS; j++) { + tcp_lost.hill[j].l = TCP_O_NOP; + tcp_lost.hill[j].r = TCP_O_NOP; } - break; } + + tcp_update_ack_edge(); + return; } - debug_cond(DEBUG_INT_STATE, "\n"); - if (!IS_ENABLED(CONFIG_PROT_TCP_SACK) || tcp_lost.len <= TCP_OPT_LEN_2) - sack_idx = 0; -} + + if (i == TCP_SACK_HILLS) { + tcp_update_ack_edge(); + return; + } + + if (cnt < TCP_SACK_HILLS) { + cnt_move = cnt - i; + cnt++; + } else { + cnt = TCP_SACK_HILLS; + cnt_move = TCP_SACK_HILLS - i; + } + + if (cnt_move > 0) + memmove(&tcp_lost.hill[i + 1], + &tcp_lost.hill[i], + cnt_move * sizeof(struct sack_edges)); + + tcp_lost.hill[i].l = tcp_seq_num; + tcp_lost.hill[i].r = tcp_seq_num + len; + tcp_lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; + + tcp_update_ack_edge(); +}; /** * tcp_parse_options() - parsing TCP options @@ -509,7 +487,6 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) u8 tcp_push = tcp_flags & TCP_PUSH; u8 tcp_ack = tcp_flags & TCP_ACK; u8 action = TCP_DATA; - int i; /* * tcp_flags are examined to determine TX action in a given state @@ -536,6 +513,7 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) action = TCP_SYN | TCP_ACK; tcp_seq_init = tcp_seq_num; tcp_ack_edge = tcp_seq_num + 1; + tcp_lost.len = TCP_OPT_LEN_2; current_tcp_state = TCP_SYN_RECEIVED; } else if (tcp_ack || tcp_fin) { action = TCP_DATA; @@ -552,13 +530,7 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) action |= TCP_ACK; tcp_seq_init = tcp_seq_num; tcp_ack_edge = tcp_seq_num + 1; - sack_idx = 0; - edge_a[sack_idx].se.l = tcp_ack_edge; - edge_a[sack_idx].se.r = tcp_ack_edge; - prev_len = 0; current_tcp_state = TCP_ESTABLISHED; - for (i = 0; i < TCP_SACK; i++) - edge_a[i].st = NOPKT; if (tcp_syn && tcp_ack) action |= TCP_PUSH; From patchwork Sat Sep 21 03:43:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988103 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=NPwhwwr4; 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) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X9Zrb22chz1y1t for ; Sat, 21 Sep 2024 13:44:47 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 02C5488582; Sat, 21 Sep 2024 05:44:14 +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="NPwhwwr4"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9327588995; Sat, 21 Sep 2024 05:44:12 +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 7FDC58870D for ; Sat, 21 Sep 2024 05:44: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=arcselector10001; d=microsoft.com; cv=none; b=pLTsX98BTybor/TrHfV9uZWmf5D8+qxctNjoGnLYn8Ngr/v1Rqn342ft3B2BST436mLMPB6t2fKjZ3UK61wEtIxWqZQNhAIN2t8/eSdrsRIgXgceSKrTNEiTLfW+jQb/16yhuJrHfa5qaXmFQKs960SMVkj3Dtcz0XYl7X4mP4+miTdTC93FHLdAzgT9kMQCzCfbxd1PJSR/DqBilI1KQIVGG1Pf7WeY924DMmAcvynPM4Fqj2DLQv+UlY6MhJuZOVEO3Z8Y06zzNzADAw2YQF1YcR3/6HTbvDmQ0e/wzLdelzhuT2VfjeSCQWgUnLs8R94qpPlEnRLVhHpA8Q9Avg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=IWzGTpR38lDfJGHf19A3hY4ITndBFti+Z0yj+Gz4HoI=; b=RYEmyweO+dJvEnyjfjp+fzhyqclICyaCpA1Yu5fAi8MuycSg8yWE8HlLu262PahKG4Yxft88pj1NVh5st2eBJdeRqm4De9TKuL96ZEG4FQbldJUvEVadoFQIqiRjf10ZFY16kiQVyMZr6J735XjA8cpmr3xTwsuuXe6VCcte0A+/KUzQRmbtmQHa9yZLhct9DMVFtM8CH7fLf8RiS3jTkxH+sksRWpWYIBFAVM92yaHAZzxkizXz4ErZIkW3UN0/QhRPIKpX0ix+sqS0pZ4gTrsNDEm6ZlpIznnKQY4SKRwNFgLnimJuowvtHbOEA8XE3kiXTJseWYC2+NDqBVal/Q== 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=IWzGTpR38lDfJGHf19A3hY4ITndBFti+Z0yj+Gz4HoI=; b=NPwhwwr4WzcjJ9Y7oAcqiO5FClYuMOMtTb21PbxkqHa1svEKsabGvrjc2FkLxF5j7iT1IrAUSQPn4D/6LhQbzlTafYBR31x9hUSMvO3jgoLJlp+AYwcLK97sEVLmgqywBRsOmkwI0nbFVkWL4ePhdzYOGYLVvdBaywj0nPkUAnSZ/U1gMtJjJbow051Tf7hpRv6NYRLl+mNl7nx0sNdevThL189epT1S8m1d7t9Pp7t6VfoUT3TzpgmM9FzTqQXwC6aptR3u2wqeJ+GbjommbVNKdGjA2P03p6kmkKdJqZpoMBLZ/ZmCMkUN1DJL+RSPTHRERgvi/Uge+W3rIRseew== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:06 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:06 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 03/13] net/tcp: put connection specific data into a tcp_stream structure Date: Sat, 21 Sep 2024 06:43:43 +0300 Message-ID: <20240921034353.1298452-4-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: 38dedd00-f53a-4c8a-790b-08dcd9efa497 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: /0IlLXIkX8IhiOy96KpCYD3jDcuD9TxJOD0xLgPc/ZgPZ3Aebe2UvkiGH3tubqJP7VBdWsInOgr1vJutLSkCGoqpLlQySIy9OQxjfQFX1nmmsXdX+lgdn0KjnzibvrMMx2YfcJySHRPcji7RuRKbT9lmFi+tsL3cmoFsxiOKzVFmOTGg8SCrYrdBFdUOS4bnyg8AVFrN1hJuORUxWTdUbOKD8pQjwW4T+itXxFmo9wUhFGwCo4M8Ts8eTTfb4XOqtATBFa7AUW7iGk/8XJAmuGqkWJWQr6g35Xl8SHtnq5jL4o4wMCYPU1rWSuz1Lt+cDEh/imXBLD9u9TOjpyM2SOeOLZcnVmtexwJEJ2REsQOG/sJaoR04E5yH5MlqIlv/fTLyGzVBTrvpNSb3ZOKMmx6SboYaZpVhmnXAJbNEo6DU6cfAX3H+efWUQpgy7Ec0KiJDGjcJSt191OEbcKewzRKITGO2ivKM5KQ4ZT0KsTfUVJS0jbNciU/x79VFDhj2ivv0gy6+uL5YpXdQUlb9bLKTDaQqXUaayPph2xPRr6Xt251HWT2HX53QyXYM/iIrje6I9Xl+mVc388rPT8O4ipDPeNMPFwb7AWDuxKR/yfDugJfgBbRVZCo87p00koqJsQhtb3PsPXpp8hlZI2HpBLzaC9d4OBkyz85V+MqvMMib7vWMd8Ge3GzQQVU7FnvlsVoVKtFqfCzt76ZgRUoPpfuMhJKqbp3i0WFDmT1IxJC/49d2KFPQzELs3K+vAOpIiWphC64vEGaSFN2T+Mn/LxJ0Ix1RS0BnYCh882kpwsZjmOzEJmzyEOeWF+eb4hTv1vPEOQpO5RvAzemi3ClR/kGicBZ0Uj1Cdl65VI0o0Uu3Xa1cV53N3B76g4Z1T4Gg4Fx0THtFA178MY2h/R3spc5orYIXVtRmbqEGnL7I+w5OmNCKs1IpAuOHLljWyulh3R661rTH2A7QteUSc9/ELsq/6pnuEaIDCCUUyWWEGELbfJRicM7DgHncKeKnNKXapzrtkKvtyOdgfvX/wMUAnqQZreycJ0o5Hf3r3qs/XyGrYubNgpjzMdSi1/gDPuH1hx09vedBk0EH7bbpkX8nbRkfgyM2hfJ+VzG44Yhfq1AF2RH5nKJOYRnyVpVaV36WMthm7BRRmvKKRDOS1XoIhEregHgT9vwSXtZi0f8/SJU8d9E/YdDFavOXNB3Ax3zHhd0fSvFR4QRPDzFQhvhXLb64C85bbLndYyDML2WCtYrDMO91pGG51vP8L9O7rSqmk0gg/iMy6btReKtGihXSFTnkMSA183Z1j1fRyMxQHgLbxmsPhj9DePNFRQ3Gl+hhm9q/msQ7CsM1lri5cYrXFg== 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: W0UBTzD7xXxs4tZ2G5y6zPrNiAQPP/TmI7crYBNt+UXxv2VbVOzxCQCKy2KeMvu2VqMyCaTurQ7Cs9PIVBNt+bUbFY0AM8tl+9b6jj5h8gLSpzfwGYX5T79FhDpO9GeowBYnhWHz8i7ceO45D/4DsMnlX/OWGDCg0Bsmq8O3k++2OGGBbM1PvAquuWxuYgoxwfikOsAEut+WfGG0QTbjiCKhIKIkLcc91r7b0h4Ak9zaPsee8l/G5Uk+kGpQloiy5Ywj5JF3LcKbc46D6/6WWWMSlTLMx8Yb2x5Ryp2EAB9ANjskRHzJlnQW1bmIdOLuUwMoX6+rbe06qurt8u4gtB/EF7ot4fW2u3v3gqIgq8NXvp7zmjWfPDY0s21VjOobznK36lIpJ5lizkp8lz+SqXmAsaysz1qShKHWk4YOgdq5Ywd3nYTY7s4En7+WeQcYefUAS0QL9VG3QTFhZ9y42mzUCnpenjYGjfm1UhoBdY0iArcesoVa2M+PIsMUE3bYiD/GPbEzsrjz8sR32n00C6ZuYOGMjKOL6TijfO+EeK4FEj/ZHAs0NqBLS3V+BAz4njwezm1TcPh6M/MkW/syR6gHAS9H0SCDuMyvswuSiqENb0eKa2w5mIa6e6uFnwR1shUDKVnwvUaAxVO0rWwjwf/XnMECOY5nj6STofMjulZEbY7K/uTVxKvp8JhGYekYx/DtpQRf9qiiV8PHK0WG+PAnBOnwz3NDwJkFV4WIrHmAKZRvtFneKIhpLnpqvGgC8S31qRWQrdO/f0cBNL2v8iY7XCVwoJnzIGGTeL5HDeJ5sTTJnT/r/R2HqgYhIJl2KkXaLNlWRuVjUYgM73xAUSZpRL375KiDnLjiySxsFfWW08raTLlZL9xUv3SXdwr4RJbRrKQogtw7FzSYBjijmsu+nac75CjfmOPnw9FBvuBarFiZn6ZvvL2VMhljGPTji4yUSm4Mwp0vZBvZZd7ZPCxBCyRx6PdZqXXsQymcJ2UDHWkkuUBmOL+2GMPlllyoTwXarjaJZAY0bioBqFt4rcpo9lm+8zBRAJhGGfFD0fVbW6J2pdHBC/1I2q2xwU/aMWsT+TyVQXKe8SdUjcOIQQeV4zxZmqEVIuZnski/o13A0a38A05wY1qPHGufv2szEv7jcFsO/h1WTRRErwEUD/6QRRp23I9l4Ne+tmUEkqVZ2WMV2ZWivCypH2QqN+epBpU4yWNjj2YKNx9h5H9WWgiN6P/1YdaO6PB0QlvkWEIGC0A1/5rbC/XY4bVVBB4yAW4bpcRUokLcujmCS6SyOkYchGnP+ufHrk1t3nnkqJywAUB+2+ss0Z/RfNXZODnvcUcJPDzhC1RKi9eRWrRUw48kHQsMAHF8o/mRfGoYYyBx1hb0pHXd5cDHD8sCFgAKR5ZCgxHESFCNfl44MRuHjFshiOVL5cMWV0+X6iQK0A77Q1W0ui5I4OpRBVu/FT3iTtbqMmSX/aSxqHQpVjQbmmZ+brFs1K3BuWeTATSIdrbQhPMGJFW5sqd2QawiBJ+xpln0nGSyrDCyzQ/x9FBDBW0tebnBWnuXufcUyumkVGLLIoxaojd2PQ8WkpsUnA0WxaT0fqAK0CHMUhy+BPKXbmFVXN2VlZtw05d6W7b8kyw= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 38dedd00-f53a-4c8a-790b-08dcd9efa497 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:06.3015 (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: qQEMRueoC+vCfVXuVPbVPGQYispLXRLSHrZ4oiUp/cIuk6hBoeimyrrnKkRTKB2FyoNqoDiYOBZQ6fzDBaVTIkxQ7ExFhwzF1tlnms7HUhQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean no functional changes Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- include/net/tcp.h | 37 +++++++- net/net.c | 11 ++- net/tcp.c | 231 +++++++++++++++++++++++----------------------- net/wget.c | 3 +- 4 files changed, 163 insertions(+), 119 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index c29d4ce24a7..14aee64cb1c 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -277,9 +277,40 @@ enum tcp_state { TCP_FIN_WAIT_2 }; -enum tcp_state tcp_get_tcp_state(void); -void tcp_set_tcp_state(enum tcp_state new_state); -int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, +/** + * struct tcp_stream - TCP data stream structure + * + * @state: TCP connection state + * + * @seq_init: Initial receive sequence number + * @ack_edge: Receive next + * + * @loc_timestamp: Local timestamp + * @rmt_timestamp: Remote timestamp + * + * @lost: Used for SACK + */ +struct tcp_stream { + /* TCP connection state */ + enum tcp_state state; + + u32 seq_init; + u32 ack_edge; + + /* TCP option timestamp */ + u32 loc_timestamp; + u32 rmt_timestamp; + + /* TCP sliding window control used to request re-TX */ + struct tcp_sack_v lost; +}; + +struct tcp_stream *tcp_stream_get(void); + +enum tcp_state tcp_get_tcp_state(struct tcp_stream *tcp); +void tcp_set_tcp_state(struct tcp_stream *tcp, enum tcp_state new_state); +int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, + int sport, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num); /** diff --git a/net/net.c b/net/net.c index d9bc9df643f..6c5ee7e0925 100644 --- a/net/net.c +++ b/net/net.c @@ -414,7 +414,7 @@ int net_init(void) /* Only need to setup buffer pointers once. */ first_call = 0; if (IS_ENABLED(CONFIG_PROT_TCP)) - tcp_set_tcp_state(TCP_CLOSED); + tcp_set_tcp_state(tcp_stream_get(), TCP_CLOSED); } return net_init_loop(); @@ -915,6 +915,9 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, uchar *pkt; int eth_hdr_size; int pkt_hdr_size; +#if defined(CONFIG_PROT_TCP) + struct tcp_stream *tcp; +#endif /* make sure the net_tx_packet is initialized (net_init() was called) */ assert(net_tx_packet != NULL); @@ -941,8 +944,12 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, break; #if defined(CONFIG_PROT_TCP) case IPPROTO_TCP: + tcp = tcp_stream_get(); + if (tcp == NULL) + return -EINVAL; + pkt_hdr_size = eth_hdr_size - + tcp_set_tcp_header(pkt + eth_hdr_size, dport, sport, + + tcp_set_tcp_header(tcp, pkt + eth_hdr_size, dport, sport, payload_len, action, tcp_seq_num, tcp_ack_num); break; diff --git a/net/tcp.c b/net/tcp.c index 724536cb352..6646f171b83 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -24,19 +24,8 @@ #include #include -/* - * TCP sliding window control used by us to request re-TX - */ -static struct tcp_sack_v tcp_lost; - -/* TCP option timestamp */ -static u32 loc_timestamp; -static u32 rmt_timestamp; - -static u32 tcp_seq_init; -static u32 tcp_ack_edge; - static int tcp_activity_count; +static struct tcp_stream tcp_stream; /* * TCP lengths are stored as a rounded up number of 32 bit words. @@ -48,9 +37,6 @@ static int tcp_activity_count; #define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4) #define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2) -/* TCP connection state */ -static enum tcp_state current_tcp_state; - /* Current TCP RX packet handler */ static rxhand_tcp *tcp_packet_handler; @@ -60,22 +46,30 @@ static inline s32 tcp_seq_cmp(u32 a, u32 b) } /** - * tcp_get_tcp_state() - get current TCP state + * tcp_get_tcp_state() - get TCP stream state + * @tcp: tcp stream * - * Return: Current TCP state + * Return: TCP stream state */ -enum tcp_state tcp_get_tcp_state(void) +enum tcp_state tcp_get_tcp_state(struct tcp_stream *tcp) { - return current_tcp_state; + return tcp->state; } /** - * tcp_set_tcp_state() - set current TCP state + * tcp_set_tcp_state() - set TCP stream state + * @tcp: tcp stream * @new_state: new TCP state */ -void tcp_set_tcp_state(enum tcp_state new_state) +void tcp_set_tcp_state(struct tcp_stream *tcp, + enum tcp_state new_state) { - current_tcp_state = new_state; + tcp->state = new_state; +} + +struct tcp_stream *tcp_stream_get(void) +{ + return &tcp_stream; } static void dummy_handler(uchar *pkt, u16 dport, @@ -138,29 +132,30 @@ u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, struct in_addr dest, /** * net_set_ack_options() - set TCP options in acknowledge packets + * @tcp: tcp stream * @b: the packet * * Return: TCP header length */ -int net_set_ack_options(union tcp_build_pkt *b) +int net_set_ack_options(struct tcp_stream *tcp, union tcp_build_pkt *b) { b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); b->sack.t_opt.kind = TCP_O_TS; b->sack.t_opt.len = TCP_OPT_LEN_A; - b->sack.t_opt.t_snd = htons(loc_timestamp); - b->sack.t_opt.t_rcv = rmt_timestamp; + b->sack.t_opt.t_snd = htons(tcp->loc_timestamp); + b->sack.t_opt.t_rcv = tcp->rmt_timestamp; b->sack.sack_v.kind = TCP_1_NOP; b->sack.sack_v.len = 0; if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) { - if (tcp_lost.len > TCP_OPT_LEN_2) { + if (tcp->lost.len > TCP_OPT_LEN_2) { debug_cond(DEBUG_DEV_PKT, "TCP ack opt lost.len %x\n", - tcp_lost.len); - b->sack.sack_v.len = tcp_lost.len; + tcp->lost.len); + b->sack.sack_v.len = tcp->lost.len; b->sack.sack_v.kind = TCP_V_SACK; - b->sack.sack_v.hill[0].l = htonl(tcp_lost.hill[0].l); - b->sack.sack_v.hill[0].r = htonl(tcp_lost.hill[0].r); + b->sack.sack_v.hill[0].l = htonl(tcp->lost.hill[0].l); + b->sack.sack_v.hill[0].r = htonl(tcp->lost.hill[0].r); /* * These SACK structures are initialized with NOPs to @@ -168,17 +163,17 @@ int net_set_ack_options(union tcp_build_pkt *b) * SACK structures used for both header padding and * internally. */ - b->sack.sack_v.hill[1].l = htonl(tcp_lost.hill[1].l); - b->sack.sack_v.hill[1].r = htonl(tcp_lost.hill[1].r); - b->sack.sack_v.hill[2].l = htonl(tcp_lost.hill[2].l); - b->sack.sack_v.hill[2].r = htonl(tcp_lost.hill[2].r); + b->sack.sack_v.hill[1].l = htonl(tcp->lost.hill[1].l); + b->sack.sack_v.hill[1].r = htonl(tcp->lost.hill[1].r); + b->sack.sack_v.hill[2].l = htonl(tcp->lost.hill[2].l); + b->sack.sack_v.hill[2].r = htonl(tcp->lost.hill[2].r); b->sack.sack_v.hill[3].l = TCP_O_NOP; b->sack.sack_v.hill[3].r = TCP_O_NOP; } b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + TCP_TSOPT_SIZE + - tcp_lost.len)); + tcp->lost.len)); } else { b->sack.sack_v.kind = 0; b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE + @@ -194,13 +189,14 @@ int net_set_ack_options(union tcp_build_pkt *b) } /** - * net_set_ack_options() - set TCP options in SYN packets + * net_set_syn_options() - set TCP options in SYN packets + * @tcp: tcp stream * @b: the packet */ -void net_set_syn_options(union tcp_build_pkt *b) +void net_set_syn_options(struct tcp_stream *tcp, union tcp_build_pkt *b) { if (IS_ENABLED(CONFIG_PROT_TCP_SACK)) - tcp_lost.len = 0; + tcp->lost.len = 0; b->ip.hdr.tcp_hlen = 0xa0; @@ -219,14 +215,15 @@ void net_set_syn_options(union tcp_build_pkt *b) } b->ip.t_opt.kind = TCP_O_TS; b->ip.t_opt.len = TCP_OPT_LEN_A; - loc_timestamp = get_ticks(); - rmt_timestamp = 0; + tcp->loc_timestamp = get_ticks(); + tcp->rmt_timestamp = 0; b->ip.t_opt.t_snd = 0; b->ip.t_opt.t_rcv = 0; b->ip.end = TCP_O_END; } -int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, +int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, + int sport, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num) { union tcp_build_pkt *b = (union tcp_build_pkt *)pkt; @@ -249,21 +246,21 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); tcp_activity_count = 0; - net_set_syn_options(b); + net_set_syn_options(tcp, b); tcp_seq_num = 0; tcp_ack_num = 0; pkt_hdr_len = IP_TCP_O_SIZE; - if (current_tcp_state == TCP_SYN_SENT) { /* Too many SYNs */ + if (tcp->state == TCP_SYN_SENT) { /* Too many SYNs */ action = TCP_FIN; - current_tcp_state = TCP_FIN_WAIT_1; + tcp->state = TCP_FIN_WAIT_1; } else { - tcp_lost.len = TCP_OPT_LEN_2; - current_tcp_state = TCP_SYN_SENT; + tcp->lost.len = TCP_OPT_LEN_2; + tcp->state = TCP_SYN_SENT; } break; case TCP_SYN | TCP_ACK: case TCP_ACK: - pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(b); + pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(tcp, b); b->ip.hdr.tcp_flags = action; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:ACK (%pI4, %pI4, s=%u, a=%u, A=%x)\n", @@ -276,20 +273,20 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); payload_len = 0; pkt_hdr_len = IP_TCP_HDR_SIZE; - current_tcp_state = TCP_FIN_WAIT_1; + tcp->state = TCP_FIN_WAIT_1; break; case TCP_RST | TCP_ACK: case TCP_RST: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:RST (%pI4, %pI4, s=%u, a=%u)\n", &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; break; /* Notify connection closing */ case (TCP_FIN | TCP_ACK): case (TCP_FIN | TCP_ACK | TCP_PUSH): - if (current_tcp_state == TCP_CLOSE_WAIT) - current_tcp_state = TCP_CLOSING; + if (tcp->state == TCP_CLOSE_WAIT) + tcp->state = TCP_CLOSING; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%u, a=%u, A=%x)\n", @@ -297,7 +294,7 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, tcp_seq_num, tcp_ack_num, action); fallthrough; default: - pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(b); + pkt_hdr_len = IP_HDR_SIZE + net_set_ack_options(tcp, b); b->ip.hdr.tcp_flags = action | TCP_PUSH | TCP_ACK; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:dft (%pI4, %pI4, s=%u, a=%u, A=%x)\n", @@ -308,9 +305,9 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, pkt_len = pkt_hdr_len + payload_len; tcp_len = pkt_len - IP_HDR_SIZE; - tcp_ack_edge = tcp_ack_num; + tcp->ack_edge = tcp_ack_num; /* TCP Header */ - b->ip.hdr.tcp_ack = htonl(tcp_ack_edge); + b->ip.hdr.tcp_ack = htonl(tcp->ack_edge); b->ip.hdr.tcp_src = htons(sport); b->ip.hdr.tcp_dst = htons(dport); b->ip.hdr.tcp_seq = htonl(tcp_seq_num); @@ -344,78 +341,79 @@ int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len, return pkt_hdr_len; } -static void tcp_update_ack_edge(void) +static void tcp_update_ack_edge(struct tcp_stream *tcp) { - if (tcp_seq_cmp(tcp_ack_edge, tcp_lost.hill[0].l) >= 0) { - tcp_ack_edge = tcp_lost.hill[0].r; + if (tcp_seq_cmp(tcp->ack_edge, tcp->lost.hill[0].l) >= 0) { + tcp->ack_edge = tcp->lost.hill[0].r; - memmove(&tcp_lost.hill[0], &tcp_lost.hill[1], + memmove(&tcp->lost.hill[0], &tcp->lost.hill[1], (TCP_SACK_HILLS - 1) * sizeof(struct sack_edges)); - tcp_lost.len -= TCP_OPT_LEN_8; - tcp_lost.hill[TCP_SACK_HILLS - 1].l = TCP_O_NOP; - tcp_lost.hill[TCP_SACK_HILLS - 1].r = TCP_O_NOP; + tcp->lost.len -= TCP_OPT_LEN_8; + tcp->lost.hill[TCP_SACK_HILLS - 1].l = TCP_O_NOP; + tcp->lost.hill[TCP_SACK_HILLS - 1].r = TCP_O_NOP; } } /** * tcp_hole() - Selective Acknowledgment (Essential for fast stream transfer) + * @tcp: tcp stream * @tcp_seq_num: TCP sequence start number * @len: the length of sequence numbers */ -void tcp_hole(u32 tcp_seq_num, u32 len) +void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) { int i, j, cnt, cnt_move; - cnt = (tcp_lost.len - TCP_OPT_LEN_2) / TCP_OPT_LEN_8; + cnt = (tcp->lost.len - TCP_OPT_LEN_2) / TCP_OPT_LEN_8; for (i = 0; i < cnt; i++) { - if (tcp_seq_cmp(tcp_lost.hill[i].r, tcp_seq_num) < 0) + if (tcp_seq_cmp(tcp->lost.hill[i].r, tcp_seq_num) < 0) continue; - if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num + len) > 0) + if (tcp_seq_cmp(tcp->lost.hill[i].l, tcp_seq_num + len) > 0) break; - if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num) > 0) - tcp_lost.hill[i].l = tcp_seq_num; - if (tcp_seq_cmp(tcp_lost.hill[i].l, tcp_seq_num) < 0) { - len += tcp_seq_num - tcp_lost.hill[i].l; - tcp_seq_num = tcp_lost.hill[i].l; + if (tcp_seq_cmp(tcp->lost.hill[i].l, tcp_seq_num) > 0) + tcp->lost.hill[i].l = tcp_seq_num; + if (tcp_seq_cmp(tcp->lost.hill[i].l, tcp_seq_num) < 0) { + len += tcp_seq_num - tcp->lost.hill[i].l; + tcp_seq_num = tcp->lost.hill[i].l; } - if (tcp_seq_cmp(tcp_lost.hill[i].r, tcp_seq_num + len) >= 0) { - tcp_update_ack_edge(); + if (tcp_seq_cmp(tcp->lost.hill[i].r, tcp_seq_num + len) >= 0) { + tcp_update_ack_edge(tcp); return; } /* check overlapping with next hills */ cnt_move = 0; - tcp_lost.hill[i].r = tcp_seq_num + len; + tcp->lost.hill[i].r = tcp_seq_num + len; for (j = i + 1; j < cnt; j++) { - if (tcp_seq_cmp(tcp_lost.hill[j].l, tcp_lost.hill[i].r) > 0) + if (tcp_seq_cmp(tcp->lost.hill[j].l, tcp->lost.hill[i].r) > 0) break; - tcp_lost.hill[i].r = tcp_lost.hill[j].r; + tcp->lost.hill[i].r = tcp->lost.hill[j].r; cnt_move++; } if (cnt_move > 0) { if (cnt > i + cnt_move + 1) - memmove(&tcp_lost.hill[i + 1], - &tcp_lost.hill[i + cnt_move + 1], + memmove(&tcp->lost.hill[i + 1], + &tcp->lost.hill[i + cnt_move + 1], cnt_move * sizeof(struct sack_edges)); cnt -= cnt_move; - tcp_lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; + tcp->lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; for (j = cnt; j < TCP_SACK_HILLS; j++) { - tcp_lost.hill[j].l = TCP_O_NOP; - tcp_lost.hill[j].r = TCP_O_NOP; + tcp->lost.hill[j].l = TCP_O_NOP; + tcp->lost.hill[j].r = TCP_O_NOP; } } - tcp_update_ack_edge(); + tcp_update_ack_edge(tcp); return; } if (i == TCP_SACK_HILLS) { - tcp_update_ack_edge(); + tcp_update_ack_edge(tcp); return; } @@ -428,23 +426,24 @@ void tcp_hole(u32 tcp_seq_num, u32 len) } if (cnt_move > 0) - memmove(&tcp_lost.hill[i + 1], - &tcp_lost.hill[i], + memmove(&tcp->lost.hill[i + 1], + &tcp->lost.hill[i], cnt_move * sizeof(struct sack_edges)); - tcp_lost.hill[i].l = tcp_seq_num; - tcp_lost.hill[i].r = tcp_seq_num + len; - tcp_lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; + tcp->lost.hill[i].l = tcp_seq_num; + tcp->lost.hill[i].r = tcp_seq_num + len; + tcp->lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; - tcp_update_ack_edge(); + tcp_update_ack_edge(tcp); }; /** * tcp_parse_options() - parsing TCP options + * @tcp: tcp stream * @o: pointer to the option field. * @o_len: length of the option field. */ -void tcp_parse_options(uchar *o, int o_len) +void tcp_parse_options(struct tcp_stream *tcp, uchar *o, int o_len) { struct tcp_t_opt *tsopt; uchar *p = o; @@ -467,7 +466,7 @@ void tcp_parse_options(uchar *o, int o_len) break; case TCP_O_TS: tsopt = (struct tcp_t_opt *)p; - rmt_timestamp = tsopt->t_snd; + tcp->rmt_timestamp = tsopt->t_snd; break; } @@ -479,7 +478,8 @@ void tcp_parse_options(uchar *o, int o_len) } } -static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) +static u8 tcp_state_machine(struct tcp_stream *tcp, u8 tcp_flags, + u32 tcp_seq_num, int payload_len) { u8 tcp_fin = tcp_flags & TCP_FIN; u8 tcp_syn = tcp_flags & TCP_SYN; @@ -500,21 +500,21 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) debug_cond(DEBUG_INT_STATE, "TCP STATE ENTRY %x\n", action); if (tcp_rst) { action = TCP_DATA; - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; net_set_state(NETLOOP_FAIL); debug_cond(DEBUG_INT_STATE, "TCP Reset %x\n", tcp_flags); return TCP_RST; } - switch (current_tcp_state) { + switch (tcp->state) { case TCP_CLOSED: debug_cond(DEBUG_INT_STATE, "TCP CLOSED %x\n", tcp_flags); if (tcp_syn) { action = TCP_SYN | TCP_ACK; - tcp_seq_init = tcp_seq_num; - tcp_ack_edge = tcp_seq_num + 1; - tcp_lost.len = TCP_OPT_LEN_2; - current_tcp_state = TCP_SYN_RECEIVED; + tcp->seq_init = tcp_seq_num; + tcp->ack_edge = tcp_seq_num + 1; + tcp->lost.len = TCP_OPT_LEN_2; + tcp->state = TCP_SYN_RECEIVED; } else if (tcp_ack || tcp_fin) { action = TCP_DATA; } @@ -525,12 +525,12 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) tcp_flags, tcp_seq_num); if (tcp_fin) { action = action | TCP_PUSH; - current_tcp_state = TCP_CLOSE_WAIT; + tcp->state = TCP_CLOSE_WAIT; } else if (tcp_ack || (tcp_syn && tcp_ack)) { action |= TCP_ACK; - tcp_seq_init = tcp_seq_num; - tcp_ack_edge = tcp_seq_num + 1; - current_tcp_state = TCP_ESTABLISHED; + tcp->seq_init = tcp_seq_num; + tcp->ack_edge = tcp_seq_num + 1; + tcp->state = TCP_ESTABLISHED; if (tcp_syn && tcp_ack) action |= TCP_PUSH; @@ -541,15 +541,15 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) case TCP_ESTABLISHED: debug_cond(DEBUG_INT_STATE, "TCP_ESTABLISHED %x\n", tcp_flags); if (payload_len > 0) { - tcp_hole(tcp_seq_num, payload_len); + tcp_hole(tcp, tcp_seq_num, payload_len); tcp_fin = TCP_DATA; /* cause standalone FIN */ } if ((tcp_fin) && (!IS_ENABLED(CONFIG_PROT_TCP_SACK) || - tcp_lost.len <= TCP_OPT_LEN_2)) { + tcp->lost.len <= TCP_OPT_LEN_2)) { action = action | TCP_FIN | TCP_PUSH | TCP_ACK; - current_tcp_state = TCP_CLOSE_WAIT; + tcp->state = TCP_CLOSE_WAIT; } else if (tcp_ack) { action = TCP_DATA; } @@ -567,7 +567,7 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_2 (%x)\n", tcp_flags); if (tcp_ack) { action = TCP_PUSH | TCP_ACK; - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; puts("\n"); } else if (tcp_syn) { action = TCP_DATA; @@ -578,20 +578,20 @@ static u8 tcp_state_machine(u8 tcp_flags, u32 tcp_seq_num, int payload_len) case TCP_FIN_WAIT_1: debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_1 (%x)\n", tcp_flags); if (tcp_fin) { - tcp_ack_edge++; + tcp->ack_edge++; action = TCP_ACK | TCP_FIN; - current_tcp_state = TCP_FIN_WAIT_2; + tcp->state = TCP_FIN_WAIT_2; } if (tcp_syn) action = TCP_RST; if (tcp_ack) - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; break; case TCP_CLOSING: debug_cond(DEBUG_INT_STATE, "TCP_CLOSING (%x)\n", tcp_flags); if (tcp_ack) { action = TCP_PUSH; - current_tcp_state = TCP_CLOSED; + tcp->state = TCP_CLOSED; puts("\n"); } else if (tcp_syn) { action = TCP_RST; @@ -615,6 +615,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) u8 tcp_action = TCP_DATA; u32 tcp_seq_num, tcp_ack_num; int tcp_hdr_len, payload_len; + struct tcp_stream *tcp; /* Verify IP header */ debug_cond(DEBUG_DEV_PKT, @@ -643,11 +644,15 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) return; } + tcp = tcp_stream_get(); + if (tcp == NULL) + return; + tcp_hdr_len = GET_TCP_HDR_LEN_IN_BYTES(b->ip.hdr.tcp_hlen); payload_len = tcp_len - tcp_hdr_len; if (tcp_hdr_len > TCP_HDR_SIZE) - tcp_parse_options((uchar *)b + IP_TCP_HDR_SIZE, + tcp_parse_options(tcp, (uchar *)b + IP_TCP_HDR_SIZE, tcp_hdr_len - TCP_HDR_SIZE); /* * Incoming sequence and ack numbers are server's view of the numbers. @@ -657,7 +662,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) tcp_ack_num = ntohl(b->ip.hdr.tcp_ack); /* Packets are not ordered. Send to app as received. */ - tcp_action = tcp_state_machine(b->ip.hdr.tcp_flags, + tcp_action = tcp_state_machine(tcp, b->ip.hdr.tcp_flags, tcp_seq_num, payload_len); tcp_activity_count++; @@ -678,7 +683,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) } else if (tcp_action != TCP_DATA) { debug_cond(DEBUG_DEV_PKT, "TCP Action (action=%x,Seq=%u,Ack=%u,Pay=%d)\n", - tcp_action, tcp_ack_num, tcp_ack_edge, payload_len); + tcp_action, tcp_ack_num, tcp->ack_edge, payload_len); /* * Warning: Incoming Ack & Seq sequence numbers are transposed @@ -687,6 +692,6 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) net_send_tcp_packet(0, ntohs(b->ip.hdr.tcp_src), ntohs(b->ip.hdr.tcp_dst), (tcp_action & (~TCP_PUSH)), - tcp_ack_num, tcp_ack_edge); + tcp_ack_num, tcp->ack_edge); } } diff --git a/net/wget.c b/net/wget.c index f1dd7abeff6..c0a80597bfe 100644 --- a/net/wget.c +++ b/net/wget.c @@ -356,7 +356,8 @@ static void wget_handler(uchar *pkt, u16 dport, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len) { - enum tcp_state wget_tcp_state = tcp_get_tcp_state(); + struct tcp_stream *tcp = tcp_stream_get(); + enum tcp_state wget_tcp_state = tcp_get_tcp_state(tcp); net_set_timeout_handler(wget_timeout, wget_timeout_handler); packets++; From patchwork Sat Sep 21 03:43:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988104 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=NdYNa3I/; 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 4X9Zrp53rsz1y34 for ; Sat, 21 Sep 2024 13:44:58 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 66E6A888A3; Sat, 21 Sep 2024 05:44:14 +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="NdYNa3I/"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 93A6D88753; Sat, 21 Sep 2024 05:44:12 +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 EUR03-AM7-obe.outbound.protection.outlook.com (mail-am7eur03on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:260e::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 7BAC2884DB for ; Sat, 21 Sep 2024 05:44: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=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Vtg62MQr8T6wzRKf+XJe5o7r0xtc4uhFXMrpZWSWG0At5n1TbguB6qn0QrphuPxvSuamFxNzReYocqXIJmvy1x4P0zU2au8xfC03T5hBVQUYSMe5bThcuRToJ7KhLoG8e1jhDuI+2BzntwFzolGV5OUDMlBOjtCi1Vuqg5tGdj5YPOey4U2++Sbd8EW8oP/aQU/lgDHbGS9MCZryB8sUB6FuTpJA9xQI/58snMZISaDlvWeuRMqB30lN//G/LGSYw9T4/pQcnRf6xk54vk4G/OvftDs0Cvtsm71Ftjc2CIf6vKMwFL6r8I8u59Ga+bBWSI2nl8aT3oYcyop/zkjwoQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=eCl/eHTMdLRIwrG9unJZDINYFXzWhj2fOYPt7wdFjWo=; b=gt4ubWplyd8HAouc4SK7TswmSXjWp2p2cVxzaebg3O/0JSiqsyBJsl+7FPlJ1dp9prXab2n+ZTBSSe0aXwTP1QDD8pw3ZLGNvPikoR7OfThqPsEbtzn0UPdAQZMLT7xv/EGW9hLYDuvIAO4xsMj98P5uNSc4JqPSDmo3uK2AkPXpX4uXqS6dVcZohVPZKeF6HLDcMsZjwKpBIkA5qPH2GPqO8rgXh8tcqwQdlV+qoVIsDlGMGk1Eem5Thotybm5vV1rRsp/b2qlJL+ZntOr4w2FKf2q5E7IEnKg1S0Fj0oXXRCeTGYnwrJWivYU2M+MzU+mpsRdhZuj4lP7mKvgzlw== 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=eCl/eHTMdLRIwrG9unJZDINYFXzWhj2fOYPt7wdFjWo=; b=NdYNa3I/2AaGBDYhjuR37rCiPF71gDjZuAGAiv9ZCQvGjEScPGfKqbhepGx5AwiIdnbg+cKUI/S22wuba3VeJZM4IZgGATp7O5zOgWaFPNb0fxcI7zn1GvqDMhkAYgM2RC+R/GTBh2zOs1sbFcdZ7H2CPja66Z1ssSPBVFcSGyx9eURHcX/cUkhpHIXyWYVPBj5L5RZhX6ZqNl7rihVLc7N1OdMDOskrmYsJI7HJegbncL8rLWBHxz+iFsXN5zXs/64a5drjcBdW75qczjFUQicq6/HoDNqZ02molTgNDMA3/2eWgry3pLcQYsc5KDh7wiIuBwtKkFlXTPUIxnHtDg== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:07 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:07 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 04/13] net/tcp: add connection info to tcp_stream structure Date: Sat, 21 Sep 2024 06:43:44 +0300 Message-ID: <20240921034353.1298452-5-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: c96a9c76-86ce-4b93-1118-08dcd9efa570 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: vyYmMIQPIOmq8FVp/HHFxQzpSC3nkdB44QG0uoEMS8ZqyQBvSjJ31IFs6FDqeP0udTjOS2eT+tkcoys1oFSgDfU1nkTos3Ktv3xLwP8ST2Ealpew3WCOJoLK9uRCZdmjTmfdQSMbEYlx8BsrVkv9tkg0A5fzZfzVse1MLDij0vymsWeBsLGEqEDtLoruYs82KJtw4EyTzFPL570vYFwUNYkCBwfZ1iR85rz8VwDo9V9EQsNuKWcxm5tTNFs/z+sKWySdyc3APY6COC4VAZ79aQHLR87pRTuQ8ga2V233ll0hf/uuzJmUpbmsfNDRq7k2OY2EjBXy2r/7GZTvZF+Of4YfflLioZz45B79rqgvfsZCYMg4Jr4vTzR/+dEh/JeaRa4fMWUG1bHdFUW6rpjMx9GDaE20VdeOp8+kZxGfC35ehh8dDyxxx8Q0HIwk130pEvrC4abEi37y6dsRveTN/ZHbUKp5FIuqxmmom+Wfg4k/tmkqh1+diVNkOLcbt9IqlXiqO6z0TjnmPxNfZk3L4iNfgnLwn6kwc31AJPnuL0mc5ZcsOdmbOrIeZ4SIEFjWrdCmIPGJVGUilqouTVSdq8dMFJ3BJxTJE7Cy2hpDBL2QKnoh2Y/uXPWphNIAgAsv7wEOrsn/dx2JyhkGqaNPBbiSYui2TvdKEbeXS9tecnYrqvU+Oq8v/8MctzH+OxcSUt8vndxDsRIANhtMTkwOpAlReRi3rvV0WWqG5KfBbGaIROFN9a86QhVaX/TfzN44MkbW35z9PPJQiPiEkfNThia06CrStU+dpfyjD2vebrZIy2sW3AMb6kH1FAk18BbXQyC9DifJ8GWoeAgc8HIW2MedfCpZ4nepCSEWks6xfI1gDeJTco7KpMfL5ZByhAHn5ue3zYuQNDt/JKJAT30MmzISpIvTXU+FdmBASUGAciStBGH/UfMhIQcVenD51qc2+Q/KW+E07+LXzl15GGwteu2sph+ehN/CL05WccI3dYjBUdjKCjO+Lfp4rFvbC5EKFj4uszopVpEt+rC7Nx9p3tBucOOW/tsMrA6p5gKnfKw1zHhjyvZeoyndyjD5KK9dUwiA2j1TBOmnbNPwM90KGgpXdLT3lhGFVUwFwsmWNUMf6RjFu2INaEWy243/4O4U1jumvCT0D01AoAdoIC3bg9NquqFBnKR2voUT0iuHjMhPjVrWXuloGC1X9E9ybxmIz0qmlM/O9ofLRtHvgNzX1K0Bt1e01A45HasMd7Q9Gs+OlLG2kL42MqpUiBqtMSiqsEEO/cF85fTjTgg7Lur9ElwLyKMDbiU4U+X9hyBnE+2PKoGOO+OW6e/UNeedJU2Z9xfn2UWFL54fKCTywtH3Bg== 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: rrwkSh0xbqARH4HuaMmTBnVErCfjTkH6KO8lNAsPRVXnDfiABzoyGCUZoDIKELJc2qFSXN9XMzV+4owPA1JuOf/fD1BUSphB8Igf6RZrzAF/4Ym7AmVBKt2CA72dS8yFnHZsI3ULpAnimE6kQclPW3Uq/AfS7vYgCmJL5KL2nIsxuj7oGLHH1se9Bk20hfyVvAr9hUdTu8LQMlJwzPWlzolzvaiTbwYFmhWfFCv2t55mIpNPPjQVwOvu41N5EieBUBtxdWyZUxbulCKc6eNhVBxsjq/zo3o4jvytN0V9v3w4QPzLzbogr00TxUK2iha+eoW6KhP/whFrrV5eS4mXPWM1JAc9mqTkWIZvUnPQXUnRtKd8OcNzulz46dmVmDy94wfijG2Th+Ao3xUmBbr/UqRHP4JXDC4m1cuydnC7kdm1eyxNng8KDCISVGca3oaUaDbOaSiigRihry5DbkcD0GdFzNJkX/Df6sH2G0s81IVcFALVZT6UYFsjKnf2aVjVEsKMUUFi3grfnp0YdYMWEHzmTxwKvNzJup5DR44r8aVJOrKwlmUStUfTkF/FrGQcXuoTnkLnEmkF88Mma+380Q4Kv4D6WDrbKqFLtDYgII3r1RHoJ0tt47kK4EBZiADufXXVumXFRzhUiFpYHOTPK7I+QXHGh+Yy3sAcoCzNEojdqiBxD3T8DgtDMKT/QN1JrnRdBg5/V+ttAacH7xZt47n9bv1fI1tY1jDElS0O2sPNaBoFidQh1MrVcajatRPEgr9+Q7QwJ+fjvkEbxFUpLtE8WQ0Pd4WKj+1vESfBues9sORsr/1W/O3MgVNz2P30YY1/QH/FMRyN6gwRfh0aJkRX/rg9MMTViIDhEJDw7AIgfJyCtvJKT2GWzcTn33etgUjxIgZdGj+chObhIbzQW96Mb1S5zbVkYZWA74LuzLx7bBHNox+2L67wFT9XcG8OzgShIPUy2wmURnkFSA8jur/OgF7tBeGnKVZ0WnIDtr8DA7/5l5/GM8GvDe0vmW9srCErjUrEp6/g3HR7lV6ciB3Q5b9r7dGMot/xwrl3dQ17B7RQjz4mH++C4A1bDw99YEyenWgAgo6AcxHtUbHZSvpgCjpBuwUizcuMAgMYGJOzYKBYRcjxEKzvcetZEfq8oNRT7EncbnTuxTtu9zyDpnxNinu1wittQh/CgNRxle8W9dJFsSYt35LPHEnPOs2dVBWG0cvQopsLYRdFyvhsvhuuH9IA+sGQVrgJtPAVn59r/QzlcTx+z6pXM/6PWy78+N8oVw4t73PukQgRhiiU7v7PE4qol/4/WsvdZLy0DLZ2pCoiAQdc7wWR4sx+Qufl1s9qDJ9PSjNtTrv0B84hTLRQ2/mbQiF+Y5i8Ru5tO5y3g1IkMSaqw7e2jlY55ApwsrOBVcVizbQKaWoJ7y8ENkAgNn/9QE0A6LwqLltvvVyHVbqSTPg4di049EFmYaLcJqIW8i2ZS3DcrlP9yaB/baE4TrwwaFJ0ICYgqaToRnSQ3B1jhk+GIXQolLXq94Iiqyyy+iMhtbVAfrNIbTAtuEvYML1jrMsdNj7zaLcU5TYaTAWVoiHGj2uB3o9EAhSA4xkbY+SArCNCMCSHEOna8ysy2S6BicvP4rmAzs6D3e0= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: c96a9c76-86ce-4b93-1118-08dcd9efa570 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:07.7227 (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: HAf5HQ/GN0Lh6Ogo0VwLqVcBfTB9t+AIXPaMxhhbBGRMmuPw/cfZdjMTJpJvf2CzfSk3fnF2v6obFGNQuo2neTv2KYDtx96kyZuv4ZsZTkQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Changes: * Avoid use net_server_ip in tcp code, use tcp_stream data instead * Ignore packets from other connections if connection already created. This prevents us from connection break caused by other tcp stream. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- include/net.h | 5 +- include/net/tcp.h | 57 +++++++++++++++++--- net/fastboot_tcp.c | 50 +++++++++-------- net/net.c | 12 ++--- net/tcp.c | 131 ++++++++++++++++++++++++++++++++++----------- net/wget.c | 52 +++++++----------- 6 files changed, 204 insertions(+), 103 deletions(-) diff --git a/include/net.h b/include/net.h index bb2ae20f52a..b0ce13e0a9d 100644 --- a/include/net.h +++ b/include/net.h @@ -667,6 +667,7 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, /** * net_send_tcp_packet() - Transmit TCP packet. * @payload_len: length of payload + * @dhost: Destination host * @dport: Destination TCP port * @sport: Source TCP port * @action: TCP action to be performed @@ -675,8 +676,8 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, * * Return: 0 on success, other value on failure */ -int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action, - u32 tcp_seq_num, u32 tcp_ack_num); +int net_send_tcp_packet(int payload_len, struct in_addr dhost, int dport, + int sport, u8 action, u32 tcp_seq_num, u32 tcp_ack_num); int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport, int payload_len); diff --git a/include/net/tcp.h b/include/net/tcp.h index 14aee64cb1c..f224d0cae2f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -279,6 +279,9 @@ enum tcp_state { /** * struct tcp_stream - TCP data stream structure + * @rhost: Remote host, network byte order + * @rport: Remote port, host byte order + * @lport: Local port, host byte order * * @state: TCP connection state * @@ -291,6 +294,10 @@ enum tcp_state { * @lost: Used for SACK */ struct tcp_stream { + struct in_addr rhost; + u16 rport; + u16 lport; + /* TCP connection state */ enum tcp_state state; @@ -305,16 +312,53 @@ struct tcp_stream { struct tcp_sack_v lost; }; -struct tcp_stream *tcp_stream_get(void); +void tcp_init(void); + +typedef int tcp_incoming_filter(struct in_addr rhost, + u16 rport, u16 sport); + +/* + * This function sets user callback used to accept/drop incoming + * connections. Callback should: + * + Check TCP stream endpoint and make connection verdict + * - return non-zero value to accept connection + * - return zero to drop connection + * + * WARNING: If callback is NOT defined, all incoming connections + * will be dropped. + */ +void tcp_set_incoming_filter(tcp_incoming_filter *filter); + +/* + * tcp_stream_get -- Get or create TCP stream + * @is_new: if non-zero and no stream found, then create a new one + * @rhost: Remote host, network byte order + * @rport: Remote port, host byte order + * @lport: Local port, host byte order + * + * Returns: TCP stream structure or NULL (if not found/created) + */ +struct tcp_stream *tcp_stream_get(int is_new, struct in_addr rhost, + u16 rport, u16 lport); + +/* + * tcp_stream_connect -- Create new TCP stream for remote connection. + * @rhost: Remote host, network byte order + * @rport: Remote port, host byte order + * + * Returns: TCP new stream structure or NULL (if not created). + * Random local port will be used. + */ +struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport); + +enum tcp_state tcp_stream_get_state(struct tcp_stream *tcp); -enum tcp_state tcp_get_tcp_state(struct tcp_stream *tcp); -void tcp_set_tcp_state(struct tcp_stream *tcp, enum tcp_state new_state); -int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, - int sport, int payload_len, +int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num); /** * rxhand_tcp() - An incoming packet handler. + * @tcp: TCP stream * @pkt: pointer to the application packet * @dport: destination TCP port * @sip: source IP address @@ -324,8 +368,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, * @action: TCP action (SYN, ACK, FIN, etc) * @len: packet length */ -typedef void rxhand_tcp(uchar *pkt, u16 dport, - struct in_addr sip, u16 sport, +typedef void rxhand_tcp(struct tcp_stream *tcp, uchar *pkt, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len); void tcp_set_tcp_handler(rxhand_tcp *f); diff --git a/net/fastboot_tcp.c b/net/fastboot_tcp.c index d1fccbc7238..4d34fdc5a45 100644 --- a/net/fastboot_tcp.c +++ b/net/fastboot_tcp.c @@ -8,14 +8,14 @@ #include #include -static char command[FASTBOOT_COMMAND_LEN] = {0}; -static char response[FASTBOOT_RESPONSE_LEN] = {0}; +#define FASTBOOT_TCP_PORT 5554 + +static char command[FASTBOOT_COMMAND_LEN]; +static char response[FASTBOOT_RESPONSE_LEN]; static const unsigned short handshake_length = 4; static const uchar *handshake = "FB01"; -static u16 curr_sport; -static u16 curr_dport; static u32 curr_tcp_seq_num; static u32 curr_tcp_ack_num; static unsigned int curr_request_len; @@ -25,34 +25,37 @@ static enum fastboot_tcp_state { FASTBOOT_DISCONNECTING } state = FASTBOOT_CLOSED; -static void fastboot_tcp_answer(u8 action, unsigned int len) +static void fastboot_tcp_answer(struct tcp_stream *tcp, u8 action, + unsigned int len) { const u32 response_seq_num = curr_tcp_ack_num; const u32 response_ack_num = curr_tcp_seq_num + (curr_request_len > 0 ? curr_request_len : 1); - net_send_tcp_packet(len, htons(curr_sport), htons(curr_dport), + net_send_tcp_packet(len, tcp->rhost, tcp->rport, tcp->lport, action, response_seq_num, response_ack_num); } -static void fastboot_tcp_reset(void) +static void fastboot_tcp_reset(struct tcp_stream *tcp) { - fastboot_tcp_answer(TCP_RST, 0); + fastboot_tcp_answer(tcp, TCP_RST, 0); state = FASTBOOT_CLOSED; } -static void fastboot_tcp_send_packet(u8 action, const uchar *data, unsigned int len) +static void fastboot_tcp_send_packet(struct tcp_stream *tcp, u8 action, + const uchar *data, unsigned int len) { uchar *pkt = net_get_async_tx_pkt_buf(); memset(pkt, '\0', PKTSIZE); pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; memcpy(pkt, data, len); - fastboot_tcp_answer(action, len); + fastboot_tcp_answer(tcp, action, len); memset(pkt, '\0', PKTSIZE); } -static void fastboot_tcp_send_message(const char *message, unsigned int len) +static void fastboot_tcp_send_message(struct tcp_stream *tcp, + const char *message, unsigned int len) { __be64 len_be = __cpu_to_be64(len); uchar *pkt = net_get_async_tx_pkt_buf(); @@ -63,12 +66,11 @@ static void fastboot_tcp_send_message(const char *message, unsigned int len) memcpy(pkt, &len_be, 8); pkt += 8; memcpy(pkt, message, len); - fastboot_tcp_answer(TCP_ACK | TCP_PUSH, len + 8); + fastboot_tcp_answer(tcp, TCP_ACK | TCP_PUSH, len + 8); memset(pkt, '\0', PKTSIZE); } -static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, - struct in_addr sip, u16 sport, +static void fastboot_tcp_handler_ipv4(struct tcp_stream *tcp, uchar *pkt, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len) { @@ -77,8 +79,6 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, u8 tcp_fin = action & TCP_FIN; u8 tcp_push = action & TCP_PUSH; - curr_sport = sport; - curr_dport = dport; curr_tcp_seq_num = tcp_seq_num; curr_tcp_ack_num = tcp_ack_num; curr_request_len = len; @@ -89,17 +89,17 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, if (len != handshake_length || strlen(pkt) != handshake_length || memcmp(pkt, handshake, handshake_length) != 0) { - fastboot_tcp_reset(); + fastboot_tcp_reset(tcp); break; } - fastboot_tcp_send_packet(TCP_ACK | TCP_PUSH, + fastboot_tcp_send_packet(tcp, TCP_ACK | TCP_PUSH, handshake, handshake_length); state = FASTBOOT_CONNECTED; } break; case FASTBOOT_CONNECTED: if (tcp_fin) { - fastboot_tcp_answer(TCP_FIN | TCP_ACK, 0); + fastboot_tcp_answer(tcp, TCP_FIN | TCP_ACK, 0); state = FASTBOOT_DISCONNECTING; break; } @@ -111,12 +111,12 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, // Only single packet messages are supported ATM if (strlen(pkt) != command_size) { - fastboot_tcp_reset(); + fastboot_tcp_reset(tcp); break; } strlcpy(command, pkt, len + 1); fastboot_command_id = fastboot_handle_command(command, response); - fastboot_tcp_send_message(response, strlen(response)); + fastboot_tcp_send_message(tcp, response, strlen(response)); fastboot_handle_boot(fastboot_command_id, strncmp("OKAY", response, 4) == 0); } @@ -129,17 +129,21 @@ static void fastboot_tcp_handler_ipv4(uchar *pkt, u16 dport, memset(command, 0, FASTBOOT_COMMAND_LEN); memset(response, 0, FASTBOOT_RESPONSE_LEN); - curr_sport = 0; - curr_dport = 0; curr_tcp_seq_num = 0; curr_tcp_ack_num = 0; curr_request_len = 0; } +static int incoming_filter(struct in_addr rhost, u16 rport, u16 lport) +{ + return (lport == FASTBOOT_TCP_PORT); +} + void fastboot_tcp_start_server(void) { printf("Using %s device\n", eth_get_name()); printf("Listening for fastboot command on tcp %pI4\n", &net_ip); + tcp_set_incoming_filter(incoming_filter); tcp_set_tcp_handler(fastboot_tcp_handler_ipv4); } diff --git a/net/net.c b/net/net.c index 6c5ee7e0925..b33ea59a9fa 100644 --- a/net/net.c +++ b/net/net.c @@ -414,7 +414,7 @@ int net_init(void) /* Only need to setup buffer pointers once. */ first_call = 0; if (IS_ENABLED(CONFIG_PROT_TCP)) - tcp_set_tcp_state(tcp_stream_get(), TCP_CLOSED); + tcp_init(); } return net_init_loop(); @@ -899,10 +899,10 @@ int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport, } #if defined(CONFIG_PROT_TCP) -int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action, - u32 tcp_seq_num, u32 tcp_ack_num) +int net_send_tcp_packet(int payload_len, struct in_addr dhost, int dport, + int sport, u8 action, u32 tcp_seq_num, u32 tcp_ack_num) { - return net_send_ip_packet(net_server_ethaddr, net_server_ip, dport, + return net_send_ip_packet(net_server_ethaddr, dhost, dport, sport, payload_len, IPPROTO_TCP, action, tcp_seq_num, tcp_ack_num); } @@ -944,12 +944,12 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, break; #if defined(CONFIG_PROT_TCP) case IPPROTO_TCP: - tcp = tcp_stream_get(); + tcp = tcp_stream_get(0, dest, dport, sport); if (tcp == NULL) return -EINVAL; pkt_hdr_size = eth_hdr_size - + tcp_set_tcp_header(tcp, pkt + eth_hdr_size, dport, sport, + + tcp_set_tcp_header(tcp, pkt + eth_hdr_size, payload_len, action, tcp_seq_num, tcp_ack_num); break; diff --git a/net/tcp.c b/net/tcp.c index 6646f171b83..0c32c5d7c92 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -26,6 +26,7 @@ static int tcp_activity_count; static struct tcp_stream tcp_stream; +static tcp_incoming_filter *incoming_filter; /* * TCP lengths are stored as a rounded up number of 32 bit words. @@ -40,40 +41,95 @@ static struct tcp_stream tcp_stream; /* Current TCP RX packet handler */ static rxhand_tcp *tcp_packet_handler; +#define RANDOM_PORT_START 1024 +#define RANDOM_PORT_RANGE 0x4000 + +/** + * random_port() - make port a little random (1024-17407) + * + * Return: random port number from 1024 to 17407 + * + * This keeps the math somewhat trivial to compute, and seems to work with + * all supported protocols/clients/servers + */ +static uint 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) || + !incoming_filter(rhost, rport, lport)) + return NULL; + + return tcp_stream_add(rhost, rport, lport); } -static void dummy_handler(uchar *pkt, u16 dport, - struct in_addr sip, u16 sport, +static void dummy_handler(struct tcp_stream *tcp, uchar *pkt, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len) { @@ -222,8 +278,7 @@ void net_set_syn_options(struct tcp_stream *tcp, union tcp_build_pkt *b) b->ip.end = TCP_O_END; } -int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, - int sport, int payload_len, +int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, u8 action, u32 tcp_seq_num, u32 tcp_ack_num) { union tcp_build_pkt *b = (union tcp_build_pkt *)pkt; @@ -243,7 +298,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, case TCP_SYN: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:SYN (%pI4, %pI4, sq=%u, ak=%u)\n", - &net_server_ip, &net_ip, + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); tcp_activity_count = 0; net_set_syn_options(tcp, b); @@ -264,13 +319,13 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, b->ip.hdr.tcp_flags = action; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:ACK (%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num, + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num, action); break; case TCP_FIN: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:FIN (%pI4, %pI4, s=%u, a=%u)\n", - &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); payload_len = 0; pkt_hdr_len = IP_TCP_HDR_SIZE; tcp->state = TCP_FIN_WAIT_1; @@ -279,7 +334,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, case TCP_RST: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:RST (%pI4, %pI4, s=%u, a=%u)\n", - &net_server_ip, &net_ip, tcp_seq_num, tcp_ack_num); + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); tcp->state = TCP_CLOSED; break; /* Notify connection closing */ @@ -290,7 +345,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, debug_cond(DEBUG_DEV_PKT, "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &net_server_ip, &net_ip, + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num, action); fallthrough; default: @@ -298,7 +353,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, b->ip.hdr.tcp_flags = action | TCP_PUSH | TCP_ACK; debug_cond(DEBUG_DEV_PKT, "TCP Hdr:dft (%pI4, %pI4, s=%u, a=%u, A=%x)\n", - &net_server_ip, &net_ip, + &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num, action); } @@ -308,8 +363,8 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, tcp->ack_edge = tcp_ack_num; /* TCP Header */ b->ip.hdr.tcp_ack = htonl(tcp->ack_edge); - b->ip.hdr.tcp_src = htons(sport); - b->ip.hdr.tcp_dst = htons(dport); + b->ip.hdr.tcp_src = htons(tcp->lport); + b->ip.hdr.tcp_dst = htons(tcp->rport); b->ip.hdr.tcp_seq = htonl(tcp_seq_num); /* @@ -332,10 +387,10 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int dport, b->ip.hdr.tcp_xsum = 0; b->ip.hdr.tcp_ugr = 0; - b->ip.hdr.tcp_xsum = tcp_set_pseudo_header(pkt, net_ip, net_server_ip, + b->ip.hdr.tcp_xsum = tcp_set_pseudo_header(pkt, net_ip, tcp->rhost, tcp_len, pkt_len); - net_set_ip_header((uchar *)&b->ip, net_server_ip, net_ip, + net_set_ip_header((uchar *)&b->ip, tcp->rhost, net_ip, pkt_len, IPPROTO_TCP); return pkt_hdr_len; @@ -616,19 +671,26 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) u32 tcp_seq_num, tcp_ack_num; int tcp_hdr_len, payload_len; struct tcp_stream *tcp; + struct in_addr src; /* Verify IP header */ debug_cond(DEBUG_DEV_PKT, "TCP RX in RX Sum (to=%pI4, from=%pI4, len=%d)\n", &b->ip.hdr.ip_src, &b->ip.hdr.ip_dst, pkt_len); - b->ip.hdr.ip_src = net_server_ip; + /* + * src IP address will be destroyed by TCP checksum verification + * algorithm (see tcp_set_pseudo_header()), so remember it before + * it was garbaged. + */ + src.s_addr = b->ip.hdr.ip_src.s_addr; + b->ip.hdr.ip_dst = net_ip; b->ip.hdr.ip_sum = 0; if (tcp_rx_xsum != compute_ip_checksum(b, IP_HDR_SIZE)) { debug_cond(DEBUG_DEV_PKT, "TCP RX IP xSum Error (%pI4, =%pI4, len=%d)\n", - &net_ip, &net_server_ip, pkt_len); + &net_ip, &src, pkt_len); return; } @@ -640,12 +702,15 @@ 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(); - if (tcp == NULL) + 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) return; tcp_hdr_len = GET_TCP_HDR_LEN_IN_BYTES(b->ip.hdr.tcp_hlen); @@ -676,9 +741,9 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) "TCP Notify (action=%x, Seq=%u,Ack=%u,Pay%d)\n", tcp_action, tcp_seq_num, tcp_ack_num, payload_len); - (*tcp_packet_handler) ((uchar *)b + pkt_len - payload_len, b->ip.hdr.tcp_dst, - b->ip.hdr.ip_src, b->ip.hdr.tcp_src, tcp_seq_num, - tcp_ack_num, tcp_action, payload_len); + (*tcp_packet_handler) (tcp, (uchar *)b + pkt_len - payload_len, + tcp_seq_num, tcp_ack_num, tcp_action, + payload_len); } else if (tcp_action != TCP_DATA) { debug_cond(DEBUG_DEV_PKT, @@ -689,9 +754,13 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) * Warning: Incoming Ack & Seq sequence numbers are transposed * here to outgoing Seq & Ack sequence numbers */ - net_send_tcp_packet(0, ntohs(b->ip.hdr.tcp_src), - ntohs(b->ip.hdr.tcp_dst), + net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, (tcp_action & (~TCP_PUSH)), tcp_ack_num, tcp->ack_edge); } } + +struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport) +{ + return tcp_stream_add(rhost, rport, random_port()); +} diff --git a/net/wget.c b/net/wget.c index c0a80597bfe..ad5db21e97e 100644 --- a/net/wget.c +++ b/net/wget.c @@ -27,9 +27,8 @@ static const char http_eom[] = "\r\n\r\n"; static const char http_ok[] = "200"; static const char content_len[] = "Content-Length"; static const char linefeed[] = "\r\n"; -static struct in_addr web_server_ip; -static int our_port; static int wget_timeout_count; +struct tcp_stream *tcp; struct pkt_qd { uchar *pkt; @@ -137,22 +136,19 @@ static void wget_send_stored(void) int len = retry_len; unsigned int tcp_ack_num = retry_tcp_seq_num + (len == 0 ? 1 : len); unsigned int tcp_seq_num = retry_tcp_ack_num; - unsigned int server_port; uchar *ptr, *offset; - server_port = env_get_ulong("httpdstp", 10, SERVER_PORT) & 0xffff; - switch (current_wget_state) { case WGET_CLOSED: debug_cond(DEBUG_WGET, "wget: send SYN\n"); current_wget_state = WGET_CONNECTING; - net_send_tcp_packet(0, server_port, our_port, action, + net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, action, tcp_seq_num, tcp_ack_num); packets = 0; break; case WGET_CONNECTING: pkt_q_idx = 0; - net_send_tcp_packet(0, server_port, our_port, action, + net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, action, tcp_seq_num, tcp_ack_num); ptr = net_tx_packet + net_eth_hdr_size() + @@ -167,14 +163,14 @@ static void wget_send_stored(void) memcpy(offset, &bootfile3, strlen(bootfile3)); offset += strlen(bootfile3); - net_send_tcp_packet((offset - ptr), server_port, our_port, + net_send_tcp_packet((offset - ptr), tcp->rhost, tcp->rport, tcp->lport, TCP_PUSH, tcp_seq_num, tcp_ack_num); current_wget_state = WGET_CONNECTED; break; case WGET_CONNECTED: case WGET_TRANSFERRING: case WGET_TRANSFERRED: - net_send_tcp_packet(0, server_port, our_port, action, + net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, action, tcp_seq_num, tcp_ack_num); break; } @@ -339,10 +335,8 @@ static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, /** * wget_handler() - TCP handler of wget + * @tcp: TCP stream * @pkt: pointer to the application packet - * @dport: destination TCP port - * @sip: source IP address - * @sport: source TCP port * @tcp_seq_num: TCP sequential number * @tcp_ack_num: TCP acknowledgment number * @action: TCP action (SYN, ACK, FIN, etc) @@ -351,13 +345,11 @@ static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, * In the "application push" invocation, the TCP header with all * its information is pointed to by the packet pointer. */ -static void wget_handler(uchar *pkt, u16 dport, - struct in_addr sip, u16 sport, +static void wget_handler(struct tcp_stream *tcp, uchar *pkt, u32 tcp_seq_num, u32 tcp_ack_num, u8 action, unsigned int len) { - struct tcp_stream *tcp = tcp_stream_get(); - enum tcp_state wget_tcp_state = tcp_get_tcp_state(tcp); + enum tcp_state wget_tcp_state = tcp_stream_get_state(tcp); net_set_timeout_handler(wget_timeout, wget_timeout_handler); packets++; @@ -441,26 +433,13 @@ static void wget_handler(uchar *pkt, u16 dport, } } -#define RANDOM_PORT_START 1024 -#define RANDOM_PORT_RANGE 0x4000 - -/** - * random_port() - make port a little random (1024-17407) - * - * Return: random port number from 1024 to 17407 - * - * This keeps the math somewhat trivial to compute, and seems to work with - * all supported protocols/clients/servers - */ -static unsigned int random_port(void) -{ - return RANDOM_PORT_START + (get_timer(0) % RANDOM_PORT_RANGE); -} - #define BLOCKSIZE 512 void wget_start(void) { + struct in_addr web_server_ip; + unsigned int server_port; + image_url = strchr(net_boot_file_name, ':'); if (image_url > 0) { web_server_ip = string_to_ip(net_boot_file_name); @@ -513,8 +492,6 @@ void wget_start(void) wget_timeout_count = 0; current_wget_state = WGET_CLOSED; - our_port = random_port(); - /* * Zero out server ether to force arp resolution in case * the server ip for the previous u-boot command, for example dns @@ -523,6 +500,13 @@ void wget_start(void) memset(net_server_ethaddr, 0, 6); + server_port = env_get_ulong("httpdstp", 10, SERVER_PORT) & 0xffff; + tcp = tcp_stream_connect(web_server_ip, server_port); + if (tcp == NULL) { + net_set_state(NETLOOP_FAIL); + return; + } + wget_send(TCP_SYN, 0, 0, 0); } From patchwork Sat Sep 21 03:43:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988105 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=jT9HudSh; 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 4X9Zs309vcz1y2P for ; Sat, 21 Sep 2024 13:45:11 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D4B2A88AE8; Sat, 21 Sep 2024 05:44:17 +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="jT9HudSh"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 828C3889AA; Sat, 21 Sep 2024 05:44:14 +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-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2614::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 808788863E for ; Sat, 21 Sep 2024 05:44: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=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=V+mCtN9IrNL2nX5BWA8fjd1sbDMDr7hi73JU32idAMcdR95aMgd9fKrTDhzA96QPXZSOteZkQGUnbbrOyYQAOcRGGTtmzSeaWSXh1XdMrY4ztlm00uTRnFRnDOeYNwkH6l2ckszzQOLWWQUbFwHgBapxS/EvrRbOfjJmtBbDb80RR8HE7WDb5fRo0C/rNkTAHNMsGnIiIIIHZO2pQSyR1Bs67bfBKp5mW8tHMfOZ5z/8AmxEH9DshhOjh3cFU/qphE8yczqw/zPPQnqTzXuQFCMhQ+TrsBAPAb0kO+mFxUj1XJgTbEMeR63B1WZXVm22vlbaHh2/z8hCqgxpoZHXUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=V1W/OM+rApXuK7t+R9S3YJe3h+F7fm++LQERW7aZmpA=; b=edFn3VJaSwPviA9g/GKxxGxOA46a3J0CLuSEUvbf75J4FJgFzuT8YAyiey9gLcsIpr4l0FKZhh5D2IRbGSiGBXazt2xGQQBWED4toLTtUg27e9ZUAbsgvHdc/l7xaclm1Lqu+FE0xOSpOR/MhZCsNHcvZYFGW6uAJiiYVV7PFsfEp/+UWTDX1dPGApJui8Sg4eglxwb5xnzp1Pt3n/QqVLDSxpoHef+hxyg5HhTSutsFZY9JhPZRhI9GJHejAVQRRFVrctbKopoWVHMfcCDkfISKfZ54/2p+TI/byGrQYkZIKELWJvmf4EdYAapWS31q1/DQqh7cePUzNwFxdT3JIg== 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=V1W/OM+rApXuK7t+R9S3YJe3h+F7fm++LQERW7aZmpA=; b=jT9HudShzBfHuCcGYrP3rW5bEHGbTAz/nAiReXxKFMKldvtVIoC7d0nLrDTi/BI5c6DbOgKnGe5+ndtT52a9xRD9w9Ei9r846hwL6MkmtpaGnk9PAQVzWYg+dQySzVxbWVDEkrcBAowULGh+tNi+uLsie+Qe0djN+CA/NOQW+L6EPIamc7bCm4yw7j4r25S2prYBhxWC8XnTINe88k7dNCQ8Fj7JtRzlfrYD7tqXjETJLbsz0VLZMxBfddZaiL4aiwbIaHLIrt6k9ADnAZILHlBBwmX1Z0M5riNzeTZixkdJu4eKLd5BsLvdrxE62uVTA6cUPnQbKHfrUETUB2HNxg== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:09 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:09 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 05/13] net/tcp: rename ack_edge and seq_init to more common rcv_nxt and irs Date: Sat, 21 Sep 2024 06:43:45 +0300 Message-ID: <20240921034353.1298452-6-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: ae0dc4ef-4598-4697-f441-08dcd9efa646 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: AldNpYfWwJty35uigZeCiTuRJ5C3FIkjQvLVCFO1Kj0p1soHyvNBjBx25NBpSGszMpQoRaZpOLK19vILwKAhmYNYwJsgCwzganwu9Xls5cXecvtimsUshM4Ebpshrw5VVv0RTdCCKNa5w7LBO8m8h2fABIPJ8bRyjmyLeTOyLvQj9NFfRYFsCng8MKSRGwHtx3Wrj9c6uaSAla2ML8T7iH/ctOxlJdb4/KgMcyo/ZxT78U1yPFvMSyJaL/voZ42D7ZyY/9aJ+Dgu0RWQyYLMc9+MMWmYdiRaAOv5r/nh/dYe/OGRtOqqcZCMLEgh1vHp36Et3X0q8sf01DgV6k0bWItSyDPhj+wP1sBOJ/rYuZmANVgnm70nX60WgVJDTpv1NnFrMCGmg33ze6e7ZeXlFYJO3Q3vzvuGJe/FMyJ4XRlQvGGGJw7VJsybtVYb3FdA//305jjgeZ6BHTQx7nBARlpplajh1BzkPiPvFcVkSJOvb8tYLClRcUp+ETOSVnrFZEnEGQtpaubX53qH1C3rr7Rti1dgpAwjYyekNnxhEKTnJiClnNzI9QV8uaU5lZ+HytbTUkbB0vVmc8hMy2vZT7+4VacFoY7XSYd736IwtFJHljZtfsBLmZMjjvvU+COtG0uHFTfoXAmcmpg/d6k9tDMQ9IdeKjREWQBTigQFRbu4elGFgp/HJl2iPXIg5qbqtWquJQqxxc7ZX42eiPDiRvaSUfv0YabIlIqedctR6GfpBEMKrOlCRPa8lKAEsEPnV8pOvUK8vo5vnVyI29ozao+1A5DUbdLg6GsYJIIDF458JmFbB82w+ovnA1zsU+fvbnFog76M6zoNGa/4jwuCFjbwPwx5EHaqyiY1dD1aPVL7gKjoNKPclxJchR5AtwTy/wHesi2sgsE0+mItAYOhB7QDcgBSpLvioPAlm46Aq+BxWeyubvE9b0ljI2i1XZi2iNC3t/jscWA8RhEmTBXiMJiQjc2Cg7PjBx33hngI+UoQypUTBaXQfVKbQEsJpxHbzlyP+VaubWXfxvh7YrTl5XWmZkVL9Tmjb59Jda5lV/AW7SAgjLv/o9gqaBvzWabMzGSalTJ6i4pJAIKWIZncXnYAPhNfewDD2kkwzryaAJeObV/GRa2Aa3n6npOKiEu2pNft4OFxPY2lgL1bGKS/Q3LBIaaLjVgQCgP5rvX+AIrrI9by5eLxY7QK8T70BaNn4bQKTGeZRBopttPIXvivq2fqcAKEclOcHDzcJqOKEiOBcn0yxg35/CoPNT93unyI3hR8EYo2XUyqX+qwPQHsGBjn5pSqKTTW6man8jKBEH817mFF/2VA//byBcuiv7lWzZGdP+5/WBqhu4UST76ldg== 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: PUlwgQ1EV2peo4J4zmDSn5eLJVyYOt/hsfqRoFr2pfp1zV218e8yNhTQH+yvDegaKZteYhLKTn5ZFkQJAdnJHi4/hTeblgudJ87PTGiN5NVWg/8mUFWCvMMm6EjtCWnkU7l14O1iipYNUwr14QfsoZUs1yr6G+qzEfU7rRQHTZ/u2Pm6L10CxmTJoVq5bK795SIDofio57hIKAq6D1JUnvd9f4MO4ySj/P9FCvzAcG0rIAEWooyyFckN16wz3RZwG9NHiJGNLAQmGUAfpbCzjK5xn6tnWoZ+vfXGZc8t585FxYss9Ug7dk3qQr0VRIBJTR/1uT3DHzotNh+pc2NwnlkmN2O8ScQi+L2oERzRa7xKm7fnZ1pzL1tGl65Vtq4k/1TEapFcnPL185EuC9Xyskyv/yRbUUle/9K+S29tNRP9HC+W0zBy3PYEZN2fkad/t9VXv44kG+GOLjx04pc9LnHccDQgBGTzMpQ9SzdeyW3adubzExX0rson8xsIUdSr2qyaB3DgDIL2ZnCdNOPLNLa1ujV2P3apzmUIoOf8BzZwmAz56a32eBG8Bo+29V4EyXbRTzewzhX18c53fCdhJI2Kanl08qlhUxzREIOTcRfEzt4jHqtQtY7r6sA5FDmqOXKTR/G9utG3W6QYTddwW/aFOm71jL9L84Z6NRVWGHVKc0Y7jxR4u7WRMY3rNmbAIs/p2+pFxtqt0v1CgXfCAEzwufi+CoUFtAjKSHaWY8+ljo74XZ57wk3GNT1YnWXKHopF9LLh4Z2Xqo0lpS4sVP0KzhZiHLRLnyLoH5aQp1SOVPdh35vUitC7ChcSfeawSFZUxjWnw1ZrCpzqcGTuMQRdWjXi+S7moZnM+mFgr/Sv/10YdLo+nYksWnZO++kOTKhODgl6Tx5KdV7O1lqfu3DUD5QUpFn1r1YwqQMLUG0080ENgEF7+fc06feJga+/pJo/o+fhpPeugXqVv9ujnk18FU8UII9vkf9FcBNYGu/cmbAyBcMwDlwiXdpWNtGel3mAIPRDyWG1QR3KB9Ef1UHSijsu4/KFC+YzcmwgO76AbSlyqfz+rR0n+vOBshnV/Deq8TvVQ3ybNSy5vgeczgDalKRM49xjz7fgwUK9ZuHwmcXevZwPoo7fhWNgbZ+IyqEn+R7uceu+muSExEL3uvha7uKscQbOJxFWcqE/kczb+1dQhymlznY5woZ+PPLIa/2Z9L3+K6v6hQxHmsMQ3RCtALJJC4zNYKufMvS5cHZENzBGElX+DP1cJJ8lxCoqQa0MO1ra2Yrg048WI+Ifo7d4vUWHNPvrPQV3S3V4k5UggJ1EixCM71/0XgmXg1bvK8A7AAf181LgkyhCKRV3gdrvtWyjd5ZvjjlESBjZF/h8hYxph0HQrbCJeYl2xQ5eWg1SHYyyHpIf2MQZxQZCZg/xGlgNLAfQ6jldl0uPTZRKHGMIYYpQIoZTNoIDSx/DLMedhYxkJMRBvQ0mXI/Mm211qQNatC1XTRXLq78KZS5Do7j3zkDiTgbljODQy5GqwX1KVJHU5Ii49bcyfK/h/09BdBXdxV3nb4OxIe5ogut9dYnvaDkQjgjHZVy9wG/k+hN+P9Umonth78KjABgiHjrPR4ey25F/9S1aYJHnzd8= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: ae0dc4ef-4598-4697-f441-08dcd9efa646 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:09.1211 (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: TcAmHuC6BFyIUEYo9iDwa/mC+AtuZ3vtm0rnc4dnZmuubvs1MTfhSW3SRbWQqM8Dyw2wL4hxZHcR6k7V9m6gq6SF48YF0SGJQ+i+nEX+qcc= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Use the names from RFC 9293 Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- include/net/tcp.h | 8 ++++---- net/tcp.c | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index f224d0cae2f..0694af9d5b1 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -285,8 +285,8 @@ enum tcp_state { * * @state: TCP connection state * - * @seq_init: Initial receive sequence number - * @ack_edge: Receive next + * @irs: Initial receive sequence number + * @rcv_nxt: Receive next * * @loc_timestamp: Local timestamp * @rmt_timestamp: Remote timestamp @@ -301,8 +301,8 @@ struct tcp_stream { /* TCP connection state */ enum tcp_state state; - u32 seq_init; - u32 ack_edge; + u32 irs; + u32 rcv_nxt; /* TCP option timestamp */ u32 loc_timestamp; diff --git a/net/tcp.c b/net/tcp.c index 0c32c5d7c92..7e445eaffd6 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -360,9 +360,9 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, pkt_len = pkt_hdr_len + payload_len; tcp_len = pkt_len - IP_HDR_SIZE; - tcp->ack_edge = tcp_ack_num; + tcp->rcv_nxt = tcp_ack_num; /* TCP Header */ - b->ip.hdr.tcp_ack = htonl(tcp->ack_edge); + b->ip.hdr.tcp_ack = htonl(tcp->rcv_nxt); b->ip.hdr.tcp_src = htons(tcp->lport); b->ip.hdr.tcp_dst = htons(tcp->rport); b->ip.hdr.tcp_seq = htonl(tcp_seq_num); @@ -396,10 +396,10 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, return pkt_hdr_len; } -static void tcp_update_ack_edge(struct tcp_stream *tcp) +static void tcp_update_rcv_nxt(struct tcp_stream *tcp) { - if (tcp_seq_cmp(tcp->ack_edge, tcp->lost.hill[0].l) >= 0) { - tcp->ack_edge = tcp->lost.hill[0].r; + if (tcp_seq_cmp(tcp->rcv_nxt, tcp->lost.hill[0].l) >= 0) { + tcp->rcv_nxt = tcp->lost.hill[0].r; memmove(&tcp->lost.hill[0], &tcp->lost.hill[1], (TCP_SACK_HILLS - 1) * sizeof(struct sack_edges)); @@ -434,7 +434,7 @@ void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) tcp_seq_num = tcp->lost.hill[i].l; } if (tcp_seq_cmp(tcp->lost.hill[i].r, tcp_seq_num + len) >= 0) { - tcp_update_ack_edge(tcp); + tcp_update_rcv_nxt(tcp); return; } @@ -463,12 +463,12 @@ void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) } } - tcp_update_ack_edge(tcp); + tcp_update_rcv_nxt(tcp); return; } if (i == TCP_SACK_HILLS) { - tcp_update_ack_edge(tcp); + tcp_update_rcv_nxt(tcp); return; } @@ -489,7 +489,7 @@ void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) tcp->lost.hill[i].r = tcp_seq_num + len; tcp->lost.len = TCP_OPT_LEN_2 + cnt * TCP_OPT_LEN_8; - tcp_update_ack_edge(tcp); + tcp_update_rcv_nxt(tcp); }; /** @@ -566,8 +566,8 @@ static u8 tcp_state_machine(struct tcp_stream *tcp, u8 tcp_flags, debug_cond(DEBUG_INT_STATE, "TCP CLOSED %x\n", tcp_flags); if (tcp_syn) { action = TCP_SYN | TCP_ACK; - tcp->seq_init = tcp_seq_num; - tcp->ack_edge = tcp_seq_num + 1; + tcp->irs = tcp_seq_num; + tcp->rcv_nxt = tcp_seq_num + 1; tcp->lost.len = TCP_OPT_LEN_2; tcp->state = TCP_SYN_RECEIVED; } else if (tcp_ack || tcp_fin) { @@ -583,8 +583,8 @@ static u8 tcp_state_machine(struct tcp_stream *tcp, u8 tcp_flags, tcp->state = TCP_CLOSE_WAIT; } else if (tcp_ack || (tcp_syn && tcp_ack)) { action |= TCP_ACK; - tcp->seq_init = tcp_seq_num; - tcp->ack_edge = tcp_seq_num + 1; + tcp->irs = tcp_seq_num; + tcp->rcv_nxt = tcp_seq_num + 1; tcp->state = TCP_ESTABLISHED; if (tcp_syn && tcp_ack) @@ -633,7 +633,7 @@ static u8 tcp_state_machine(struct tcp_stream *tcp, u8 tcp_flags, case TCP_FIN_WAIT_1: debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_1 (%x)\n", tcp_flags); if (tcp_fin) { - tcp->ack_edge++; + tcp->rcv_nxt++; action = TCP_ACK | TCP_FIN; tcp->state = TCP_FIN_WAIT_2; } @@ -748,7 +748,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) } else if (tcp_action != TCP_DATA) { debug_cond(DEBUG_DEV_PKT, "TCP Action (action=%x,Seq=%u,Ack=%u,Pay=%d)\n", - tcp_action, tcp_ack_num, tcp->ack_edge, payload_len); + tcp_action, tcp_ack_num, tcp->rcv_nxt, payload_len); /* * Warning: Incoming Ack & Seq sequence numbers are transposed @@ -756,7 +756,7 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) */ net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, (tcp_action & (~TCP_PUSH)), - tcp_ack_num, tcp->ack_edge); + tcp_ack_num, tcp->rcv_nxt); } } From patchwork Sat Sep 21 03:43:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988107 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=jbWLPUk4; 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 4X9ZsT4hvMz1y2P for ; Sat, 21 Sep 2024 13:45:33 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id CDEDD88B27; Sat, 21 Sep 2024 05:44:19 +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="jbWLPUk4"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 39A5488B0C; Sat, 21 Sep 2024 05:44:18 +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-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2614::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 855958863E for ; Sat, 21 Sep 2024 05:44:14 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=dnhwod9ksY4+YK63JLTvV/fYdNaMcNuIwkww5q+BYj78hzsC46akjdJw7iWPyA5D+xlyslgTd10p53axca/KCPkyk/bWbsGmmuCYu/K0QxXtna6ZxP+YShFKVJzmmDSk7myKS3vS7Sz2rPFGf/3++S6R4zLQbWQblzmkQnNs5trV/BYtG/jjoOApswqmEY1Q4mwVCLceHIjF0xRlNE9t/FMr8DhFr4oRvfxb4SMk9m+uz6+m8tTbQ5DKVmC4avJgLPOki9i7qrn0pabR3U+fZ8QMMPlaZXIyQyPWvrQACZHu+oBabQgPfPm640mR50gYVoghAytY30dlL8Xce++Tiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=TOrjz9Z2LfB7yZP8j8ck1xOOGkW5I+jODebUEPYL+Wo=; b=uXNbhS9rjzgzU88JSYKqEDT2zwg2apWQ8vAXSk68cexe/AyzO4eJKjPowWaenlEsZgOfqzEGpKMhKARiTyHWu6T47I8L5yBHhXNOn8vaqQ+lBu8wY64g7TFQXsaxrndP/SUgwgN2vwp8tWEmvSpBdQ+T4wrSgq8NbRsNeNaB0hMFzdKJ7K5z7DJf9CM2ToHRKcICv8hV+So+h1rqoCSQpyDhmPuMSeYB6keIxlI+/CyyQUE9g+fccl2WTwfL5qLNPAHUUHFDZDWme04o6ZiAv+r21r0/AtIN8Q75SFBg31mbHJOBSCm5Q76vA/jtAgleFjgvUVTgz351rn+MB9zVZQ== 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=TOrjz9Z2LfB7yZP8j8ck1xOOGkW5I+jODebUEPYL+Wo=; b=jbWLPUk4UsO51w3d28qlWQXJa5SnXGY1V/wcQIH1bhxs1kxVkUR2LVF+CvX4wfH09YWsNB6Frwl07M9pg9jO/PbnXeA1FtzZ7ZoWBs9deyPBpS7cO4xahYDhOSKo0itMhkZHrfcNbdDNHmGSgoGHr3a/0efrlPoCfmKBmeRQFKEfsUkpQgxptNsRXUmJc9aCKo4CTuivFeHbVyEIPOB+8icYBk2S7+iUcoh/+JGlXtB48wscPGYIlrBeOl8zigvlAh96KhDJPgEHwt6lY9WJce+6lNhfjHZ/i4zUgXLGq5U5QKpl0OmSoyOlFBO0EXD3phwy3IsKbpHPQNs2/3K8Gg== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:10 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:10 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 06/13] net/tcp: improve tcp framework, use better state machine Date: Sat, 21 Sep 2024 06:43:46 +0300 Message-ID: <20240921034353.1298452-7-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: 88b7092c-d415-4cb3-d9c0-08dcd9efa71d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: D93LWmdhiYHslCBarbSoQRfTtrqHeI76hzMTl19yHR9IGyLodxMA1qA4yRUjMFnKia7TlzH8d/S5XKogXNnaJmk5hyYTtu+JpQgjNXK/fxKtaMe3HW9+xuwRWNIb/3k128UMFvZpv9eEK1Jr5lflLLfofcC+4pxu2UaTMIjNyanJ5G3nO+HU8O8ePNWN9pZ9FBfcxuYnA/ZZMjRIe/evbzChXKHKmPnqJxJm7OzLj7M3Ds2B9PmFdRKR8yohRdajfVTgi6mAoCaPk5XIEnyWFcIn7HmBnyhbqCz3CIyKbTw8vrmdjYvvsozGsYFysl7tbkD79bNqTXZefXrcxESf7Z33c5wQl07Ya5E3927pO64mf7eigUR/A5TnCYaJRiFdyTFjTryPNQZnm5vdXEhfZJAOVGc/O9RsZ84fhhGUfzMWx2+Dz9ouy2F20x1qmvMw3/9NynnFroELaTj/pQOI/mHiM+vxKXxS3TjiSSV9HcWwLF/dgWzWYtWjbq5RhhGJuMRGZVbJsCPzujGUfx2hEg6bw2JlwkbPKrv58Miu+dAwqustLpLvAexBVrfhbEs5tVvddrOtSycm+KbET6B9J1IZ3MN3g3/Nn7K5XQ2xW6BtNRumiRowZytB6k+1gKz1c++LUGyfMSbSJ7c107gjqgtzFU9Mmob6gtPlPW0Dz2hxLL1Pd0yWngA0XHqawRuoWnVoU8l9MSGt7fV0kjM9rbBXOePvAMI07nQxB4ouVjpCSrRiF6N8q1CQ7fqU8j2j89IiMNZ2knFpetwSOqmFvB7Yvzy+UzE5FMhsr/GFi28i3tZ0jOOHAVUXsyiHAb026ujaTuq85VTrYYPKXz6vQp3KDuNn+yc+N2oedRxg6iNy0e/Yy4v+QlQUZclyL/i89zph9HgvWKVz1trzk5feQMwItJxMfGQBS/7t0DSYlvk9Z7JCM7CdRvNUJovHzDXWgZlgNv1i2FqxMI0fwTHS72jgpujo3nda+1Zw/i2RSLR/wBgghjespHCDz2R4fpCvYv5bTbD7By9HQC/ADSR9VeQmb7ewdxfsImJD+TEZ7cbDehf4malyEq4Evq/5Az3cEbwGm3haL+Cs4CVAJlaVWSTasnkD04YqLZBXC8boZeQlYFOjTqyJmy64Yt7F94k/qWrY14Y0kKR5wVpfCuE9U86O6oRQV4uzbdTQ0blli+XVn4xRGO3t6PlqcpFST/0aO57hiB3bKQh2IWcM/veJtedve3bPHZKQjaLJ/B17SjMTjpjQkbPjwfO5RMsj/bB5eQLPfXd/iJwJxJ44VeYUa3IXRuIxJ1Vjfu/9NLeeXkvU9Zj0SrfK0lUPXiSvXP0yU+OUP3M6U0ceoyCctw6ql+c1qiBsdlMNiZlI6hCjJEA= 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: yuw4IF5reMo0uKC5zLuFmt25G9TaOv9guQqag6FurU9cBxPIAumnLjrgMCrQjeIDXJinmDxk/x7slMksuNzZB1jAyT3KNukcNqazcHDtYM3fhBxASkRqYYjsSzDdikHv5wc9tYAkCdzVuUDdVrC5RfqkcqLWHntmO9casUGXjaCATvtvOPFBRX6f7G8TKwJE/pOIxBbNxT1rPHTR89ZgZ/9Gl6UEvggBoerCfR181pLCD3qwpeW/Gxdb+4nDDrkr6+ZIfJxd8gpTs3J/2FD7Ccp7cUg4vlDeSQamN2kbGCh8K+kuRvmcXYKT3fiSvQTLzhGRTLlFtub1fi3i/sBDkdhkRN6T8LdKX4v2DzviTpQlQUgXZUaKm+f6gZDGHbcrRGqBVdfslvghJuJsuTHwA9wWN0Yhl2fTps90eR3FHZe1ath1ny59ARXz2kN9x+KW/q/KEok82ISM0P6RnWWLZcVOtO1NdxHivGXuwmX7wR4lL+2IK95AVoweRmTDHnFL45oaH3A+L+tzfHkjt6gf4gB0KjcrYQIKTia9c8OAraeBkFgpDBP2HaACTZraPlAQt19SLQlu9K1MJ6ofxmr4kqN2bwsq/xxiOZ41ySMeTSMmsS/r1d0OVs0eT9vKA6jdN25WsveZ3fJ5yUDS15iAc4m3f9zZeyorlGzkZF74KNJ4DNGODAg0RbxAUTyG2XA4+JPOafwxxF1IpeO/N6+s+NyMjqddgHJ1QrEktaKsu48xeV3Rjd17eCW2kBy9PqCs9VXL1rCXg9AnzWOZFhhtxUYXwKTqeo0itFd3b7gC0UMXcyqGGeTUEBZ6GtQmRVZyqaeQOZGN0b1jiTkMCf2J3DEvH/vxqcS60EEahYi9jbDGl7gnw/Gul5qEfFbNKJv+V/zzgs9je9Vq/LOBLSLsL3bYM5LeCs0XuINP+yEx31rycJYET0OkRU3KOsJh+wE8a7/7fbzmcaEy8AMWHS2aeWHBHXak5OaMs3dtVPVJseLONEk/bnuVt3iocFuAUXIDXjv5q4CwyDV2k446JgDcB1fV7Rkiy/kzScPFC9g2kkhf8FHLpptZhVaEIkSVPVq3qLkd6mDecRMgM1b9bNW0dGOEJIBReg37fGig6bJCTrHv/RQwl3dgglA0gzffLFEDsl4aolA66vfE7UOM23O7L9RJma7XIg6hTcSVHA1SOTupMNHhLcPvdGTf6JCvcLfCRG9sMK79s/kL3Cqu3P0uxActeLItKASQtirb+oMcnHQNPxZ5zTT/9r1GZ50j7TWAC6R6hhjrpbywsmrB0QxN9C8udmY0aIwlLxwxahGHTYGCTXobNLEL8IyfEkx94NleWMpOy64c7a0th9VCsq9ncaZDomxquOwbJJeqXE/jv36grQ/x4QXeJmsWzYVDxs+tq3UiR22WtonmFldLCdp1XuyNvHxPnvI9gBbGIPRAYqTXBBcGHDcV2aWXe4cRoOC0iVRd6jqtnSWcX/bg49vOIwYUjUAn2C5CjWcN9jfFopqhLqP2UO2SwJy0fsksPjjaOsYz33e2L461RqZz3Y86wdWAhuMzMRuZGqCwhRcVhz7W73PGW54gmGqRMIOCqcfHfb3ekh39o8iwdZ1hOPZRpjKDeGJjoVbCh+HzncL8I40= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 88b7092c-d415-4cb3-d9c0-08dcd9efa71d X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:10.6032 (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: e3yUulvdC58zjmAjUjIpZEe5hsoMoWf4Umhl5BwKxevZHrVUHoBX6ltowa9b2zXTEmSBgdt4ICxCw/PkKQH7rAPVeWCZ/IergZTIhoXCo7Q= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Changes: * Fix initial send sequence always zero issue * Use state machine close to RFC 9293. This should make TCP transfers more reliable (now we can upload a huge array of data from the board to external server) * Improve TCP framework a lot. This should make tcp client code much more simple. * rewrite wget with new tcp stack * rewrite fastboot_tcp with new tcp stack It's quite hard to fix the initial send sequence (ISS) issue with the separate patch. A naive attempt to fix an issue inside the tcp_set_tcp_header() function will break tcp packet retransmit logic in wget and other clients. Example: Wget stores tcp_seq_num value before tcp_set_tcp_header() will be called and (on failure) retransmit the packet with the stored tcp_seq_num value. Thus: * the same ISS must allways be used (current case) * or tcp clients needs to generate a proper ISS when required. A proper ISS fix will require a big redesing comparable with a this one. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- include/net/tcp.h | 179 ++++++++-- include/net/wget.h | 8 - net/fastboot_tcp.c | 193 +++++----- net/net.c | 4 + net/tcp.c | 853 ++++++++++++++++++++++++++++++++++----------- net/wget.c | 464 +++++++----------------- 6 files changed, 1022 insertions(+), 679 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 0694af9d5b1..0b18475645d 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,27 +464,37 @@ 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); -int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, - u8 action, u32 tcp_seq_num, u32 tcp_ack_num); +enum tcp_state tcp_stream_get_state(struct tcp_stream *tcp); +enum tcp_status tcp_stream_get_status(struct tcp_stream *tcp); -/** - * 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 + +/* + * tcp_stream_rx_offs(), + * tcp_stream_tx_offs() -- Returns offset of first unacknowledged byte + * in receive/transmit stream correspondingly. + * The result is NOT affected by sin/fin flags. + * @tcp: TCP stream */ -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); +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); void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int len); 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 4d34fdc5a45..101d598012e 100644 --- a/net/fastboot_tcp.c +++ b/net/fastboot_tcp.c @@ -10,140 +10,109 @@ #define FASTBOOT_TCP_PORT 5554 -static char command[FASTBOOT_COMMAND_LEN]; -static char response[FASTBOOT_RESPONSE_LEN]; - 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 && rx_bytes >= handshake_length) { + if (memcmp(rxbuf, handshake, handshake_length)) { + printf("fastboot: bad handshake\n"); + tcp_stream_close(tcp); + return; + } -static void fastboot_tcp_send_packet(struct tcp_stream *tcp, u8 action, - const uchar *data, unsigned int len) -{ - uchar *pkt = net_get_async_tx_pkt_buf(); + tx_last_offs = 0; + tx_last_len = handshake_length; + memcpy(txbuf, handshake, handshake_length); + + data_read += handshake_length; + rx_bytes -= handshake_length; + if (rx_bytes > 0) + memmove(rxbuf, rxbuf + handshake_length, rx_bytes); + return; + } - memset(pkt, '\0', PKTSIZE); - pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; - memcpy(pkt, data, len); - fastboot_tcp_answer(tcp, action, len); - memset(pkt, '\0', PKTSIZE); + if (rx_bytes < sizeof(u64)) + return; + + memcpy(&cmd_size, rxbuf, sizeof(u64)); + cmd_size = __be64_to_cpu(cmd_size); + if (rx_bytes < sizeof(u64) + cmd_size) + return; + + saved = rxbuf[sizeof(u64) + cmd_size]; + rxbuf[sizeof(u64) + cmd_size] = '\0'; + fastboot_command_id = fastboot_handle_command(rxbuf + sizeof(u64), + txbuf + sizeof(u64)); + fastboot_handle_boot(fastboot_command_id, + strncmp("OKAY", txbuf + sizeof(u64), 4) != 0); + rxbuf[sizeof(u64) + cmd_size] = saved; + + len = strlen(txbuf + sizeof(u64)); + len_be = __cpu_to_be64(len); + memcpy(txbuf, &len_be, sizeof(u64)); + + tx_last_offs += tx_last_len; + tx_last_len = len + sizeof(u64); + + data_read += sizeof(u64) + cmd_size; + rx_bytes -= sizeof(u64) + cmd_size; + if (rx_bytes > 0) + memmove(rxbuf, rxbuf + sizeof(u64) + cmd_size, rx_bytes); } -static void fastboot_tcp_send_message(struct tcp_stream *tcp, - const char *message, unsigned int len) +static u32 tcp_stream_rx(struct tcp_stream *tcp, u32 rx_offs, void *buf, u32 len) { - __be64 len_be = __cpu_to_be64(len); - uchar *pkt = net_get_async_tx_pkt_buf(); - - memset(pkt, '\0', PKTSIZE); - pkt += net_eth_hdr_size() + IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; - // Put first 8 bytes as a big endian message length - memcpy(pkt, &len_be, 8); - pkt += 8; - memcpy(pkt, message, len); - fastboot_tcp_answer(tcp, TCP_ACK | TCP_PUSH, len + 8); - memset(pkt, '\0', PKTSIZE); + memcpy(rxbuf + rx_offs - data_read, buf, len); + + return len; } -static void fastboot_tcp_handler_ipv4(struct tcp_stream *tcp, uchar *pkt, - u32 tcp_seq_num, u32 tcp_ack_num, - u8 action, unsigned int len) +static u32 tcp_stream_tx(struct tcp_stream *tcp, u32 tx_offs, void *buf, u32 maxlen) { - int fastboot_command_id; - u64 command_size; - u8 tcp_fin = action & TCP_FIN; - u8 tcp_push = action & TCP_PUSH; - - curr_tcp_seq_num = tcp_seq_num; - curr_tcp_ack_num = tcp_ack_num; - curr_request_len = len; - - switch (state) { - case FASTBOOT_CLOSED: - if (tcp_push) { - if (len != handshake_length || - strlen(pkt) != handshake_length || - memcmp(pkt, handshake, handshake_length) != 0) { - fastboot_tcp_reset(tcp); - break; - } - fastboot_tcp_send_packet(tcp, TCP_ACK | TCP_PUSH, - handshake, handshake_length); - state = FASTBOOT_CONNECTED; - } - break; - case FASTBOOT_CONNECTED: - if (tcp_fin) { - fastboot_tcp_answer(tcp, TCP_FIN | TCP_ACK, 0); - state = FASTBOOT_DISCONNECTING; - break; - } - if (tcp_push) { - // First 8 bytes is big endian message length - command_size = __be64_to_cpu(*(u64 *)pkt); - len -= 8; - pkt += 8; - - // Only single packet messages are supported ATM - if (strlen(pkt) != command_size) { - fastboot_tcp_reset(tcp); - break; - } - strlcpy(command, pkt, len + 1); - fastboot_command_id = fastboot_handle_command(command, response); - fastboot_tcp_send_message(tcp, response, strlen(response)); - fastboot_handle_boot(fastboot_command_id, - strncmp("OKAY", response, 4) == 0); - } - break; - case FASTBOOT_DISCONNECTING: - if (tcp_push) - state = FASTBOOT_CLOSED; - break; - } + /* by design: tx_offs >= tx_last_offs */ + if (tx_offs >= tx_last_offs + tx_last_len) + return 0; - memset(command, 0, FASTBOOT_COMMAND_LEN); - memset(response, 0, FASTBOOT_RESPONSE_LEN); - curr_tcp_seq_num = 0; - curr_tcp_ack_num = 0; - curr_request_len = 0; + maxlen = tx_last_offs + tx_last_len - tx_offs; + memcpy(buf, txbuf + (tx_offs - tx_last_offs), maxlen); + + return maxlen; } -static int incoming_filter(struct in_addr rhost, u16 rport, u16 lport) +static int tcp_stream_on_create(struct tcp_stream *tcp) { - return (lport == FASTBOOT_TCP_PORT); + if (tcp->lport != FASTBOOT_TCP_PORT) + return 0; + + data_read = 0; + tx_last_offs = 0; + tx_last_len = 0; + + tcp->on_rcv_nxt_update = tcp_stream_on_rcv_nxt_update; + tcp->rx = tcp_stream_rx; + tcp->tx = tcp_stream_tx; + + return 1; } void fastboot_tcp_start_server(void) { + memset(net_server_ethaddr, 0, 6); + tcp_stream_set_on_create_handler(tcp_stream_on_create); + printf("Using %s device\n", eth_get_name()); printf("Listening for fastboot command on tcp %pI4\n", &net_ip); - - tcp_set_incoming_filter(incoming_filter); - tcp_set_tcp_handler(fastboot_tcp_handler_ipv4); } diff --git a/net/net.c b/net/net.c index b33ea59a9fa..86182cc504e 100644 --- a/net/net.c +++ b/net/net.c @@ -646,6 +646,9 @@ restart: * errors that may have happened. */ eth_rx(); +#if defined(CONFIG_PROT_TCP) + tcp_streams_poll(); +#endif /* * Abort if ctrl-c was pressed. @@ -952,6 +955,7 @@ int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport, + tcp_set_tcp_header(tcp, pkt + eth_hdr_size, payload_len, action, tcp_seq_num, tcp_ack_num); + tcp_stream_put(tcp); break; #endif default: diff --git a/net/tcp.c b/net/tcp.c index 7e445eaffd6..07c57d3ea8b 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -24,9 +24,26 @@ #include #include -static int tcp_activity_count; +/* + * The start sequence number increment for the two sequently created + * connections within the same timer tick. This number must be: + * - prime (to increase the time before the same number will be generated) + * - larger than typical MTU (to avoid similar numbers for two sequently + * created connections) + */ +#define TCP_START_SEQ_INC 2153 /* just large prime number */ + +#define TCP_SEND_RETRY 3 +#define TCP_SEND_TIMEOUT 2000UL +#define TCP_RX_INACTIVE_TIMEOUT 30000UL +#define TCP_RCV_WND_SIZE (PKTBUFSRX * TCP_MSS) + +#define TCP_PACKET_OK 0 +#define TCP_PACKET_DROP 1 + static struct tcp_stream tcp_stream; -static tcp_incoming_filter *incoming_filter; + +static int (*tcp_stream_on_create)(struct tcp_stream *tcp); /* * TCP lengths are stored as a rounded up number of 32 bit words. @@ -35,12 +52,10 @@ static tcp_incoming_filter *incoming_filter; */ #define LEN_B_TO_DW(x) ((x) >> 2) #define ROUND_TCPHDR_LEN(x) (LEN_B_TO_DW((x) + 3)) +#define ROUND_TCPHDR_BYTES(x) (((x) + 3) & ~3) #define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4) #define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2) -/* Current TCP RX packet handler */ -static rxhand_tcp *tcp_packet_handler; - #define RANDOM_PORT_START 1024 #define RANDOM_PORT_RANGE 0x4000 @@ -62,6 +77,22 @@ static inline s32 tcp_seq_cmp(u32 a, u32 b) return (s32)(a - b); } +static inline u32 tcp_get_start_seq(void) +{ + static u32 tcp_seq_inc; + u32 tcp_seq; + + tcp_seq = (get_timer(0) & 0xffffffff) + tcp_seq_inc; + tcp_seq_inc += TCP_START_SEQ_INC; + + return tcp_seq; +} + +static inline ulong msec_to_ticks(ulong msec) +{ + return msec * CONFIG_SYS_HZ / 1000; +} + /** * tcp_stream_get_state() - get TCP stream state * @tcp: tcp stream @@ -84,15 +115,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) + tcp->on_closed(tcp); + memset(tcp, 0, sizeof(struct tcp_stream)); +} + void tcp_init(void) { - incoming_filter = NULL; - tcp_stream.state = TCP_CLOSED; + static int initialized; + struct tcp_stream *tcp = &tcp_stream; + + tcp_stream_on_create = NULL; + if (!initialized) { + initialized = 1; + memset(tcp, 0, sizeof(struct tcp_stream)); + } + + tcp_stream_set_state(tcp, TCP_CLOSED); + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_destroy(tcp); } -void tcp_set_incoming_filter(tcp_incoming_filter *filter) +void tcp_stream_set_on_create_handler(int (*on_create)(struct tcp_stream *)) { - incoming_filter = filter; + tcp_stream_on_create = on_create; } static struct tcp_stream *tcp_stream_add(struct in_addr rhost, @@ -100,15 +186,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 || + tcp->state != TCP_CLOSED) + return NULL; + + tcp_stream_init(tcp, rhost, rport, lport); + if (!tcp_stream_on_create(tcp)) return NULL; - memset(tcp, 0, sizeof(struct tcp_stream)); - tcp->rhost.s_addr = rhost.s_addr; - tcp->rport = rport; - tcp->lport = lport; - tcp->state = TCP_CLOSED; - tcp->lost.len = TCP_OPT_LEN_2; return tcp; } @@ -122,30 +207,205 @@ struct tcp_stream *tcp_stream_get(int is_new, struct in_addr rhost, tcp->lport == lport) return tcp; - if (!is_new || !incoming_filter) || - !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) { + 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) { + 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 || + !tcp->tx) + 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) + 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 && + 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); } /** @@ -240,7 +500,6 @@ int net_set_ack_options(struct tcp_stream *tcp, union tcp_build_pkt *b) * This returns the actual rounded up length of the * TCP header to add to the total packet length */ - return GET_TCP_HDR_LEN_IN_BYTES(b->sack.hdr.tcp_hlen); } @@ -300,18 +559,8 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, "TCP Hdr:SYN (%pI4, %pI4, sq=%u, ak=%u)\n", &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); - tcp_activity_count = 0; net_set_syn_options(tcp, b); - tcp_seq_num = 0; - tcp_ack_num = 0; pkt_hdr_len = IP_TCP_O_SIZE; - if (tcp->state == TCP_SYN_SENT) { /* Too many SYNs */ - action = TCP_FIN; - tcp->state = TCP_FIN_WAIT_1; - } else { - tcp->lost.len = TCP_OPT_LEN_2; - tcp->state = TCP_SYN_SENT; - } break; case TCP_SYN | TCP_ACK: case TCP_ACK: @@ -328,21 +577,16 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); payload_len = 0; pkt_hdr_len = IP_TCP_HDR_SIZE; - tcp->state = TCP_FIN_WAIT_1; break; case TCP_RST | TCP_ACK: case TCP_RST: debug_cond(DEBUG_DEV_PKT, "TCP Hdr:RST (%pI4, %pI4, s=%u, a=%u)\n", &tcp->rhost, &net_ip, tcp_seq_num, tcp_ack_num); - tcp->state = TCP_CLOSED; break; /* Notify connection closing */ case (TCP_FIN | TCP_ACK): case (TCP_FIN | TCP_ACK | TCP_PUSH): - if (tcp->state == TCP_CLOSE_WAIT) - tcp->state = TCP_CLOSING; - debug_cond(DEBUG_DEV_PKT, "TCP Hdr:FIN ACK PSH(%pI4, %pI4, s=%u, a=%u, A=%x)\n", &tcp->rhost, &net_ip, @@ -382,7 +626,7 @@ int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len, * it is, then the u-boot tftp or nfs kernel netboot should be * considered. */ - b->ip.hdr.tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE); + b->ip.hdr.tcp_win = htons(tcp->rcv_wnd >> TCP_SCALE); b->ip.hdr.tcp_xsum = 0; b->ip.hdr.tcp_ugr = 0; @@ -501,6 +745,7 @@ void tcp_hole(struct tcp_stream *tcp, u32 tcp_seq_num, u32 len) void tcp_parse_options(struct tcp_stream *tcp, uchar *o, int o_len) { struct tcp_t_opt *tsopt; + struct tcp_scale *wsopt; uchar *p = o; /* @@ -515,10 +760,13 @@ void tcp_parse_options(struct tcp_stream *tcp, uchar *o, int o_len) case TCP_O_END: return; case TCP_O_MSS: - case TCP_O_SCL: case TCP_P_SACK: case TCP_V_SACK: break; + case TCP_O_SCL: + wsopt = (struct tcp_scale *)p; + tcp->rmt_win_scale = wsopt->scale; + break; case TCP_O_TS: tsopt = (struct tcp_t_opt *)p; tcp->rmt_timestamp = tsopt->t_snd; @@ -533,129 +781,333 @@ 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 && !tcp->rcv_wnd) { + if (tcp_seq_num == tcp->rcv_nxt) + return 1; + } + if (!payload_len && 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) + 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 && + 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 && + 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) { - 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; + u32 tmp_len, buf_offs, old_offs, new_offs; + u8 action; + + if (!len) + 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) + 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 && 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) +{ + 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; + + tcp_flags = b->ip.hdr.tcp_flags; - switch (tcp->state) { +// 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) + tcp->on_established(tcp); + + action = tcp_stream_fin_needed(tcp, tcp->snd_una) | TCP_ACK; + tcp_send_packet(tcp, action, tcp->snd_una, tcp->rcv_nxt, 0); + tcp_rx_user_data(tcp, tcp_seq_num, + ((char *)b) + pkt_len - payload_len, + payload_len); + return; + + case TCP_SYN_RECEIVED: case TCP_ESTABLISHED: - debug_cond(DEBUG_INT_STATE, "TCP_ESTABLISHED %x\n", tcp_flags); - if (payload_len > 0) { - tcp_hole(tcp, tcp_seq_num, payload_len); - tcp_fin = TCP_DATA; /* cause standalone FIN */ + case TCP_FIN_WAIT_1: + case TCP_FIN_WAIT_2: + case TCP_CLOSE_WAIT: + case TCP_CLOSING: + case TCP_LAST_ACK: + if (!tcp_seg_in_wnd(tcp, tcp_seq_num, payload_len)) { + if (tcp_flags & TCP_RST) + return; + action = tcp_stream_fin_needed(tcp, tcp->snd_una) | TCP_ACK; + tcp_send_packet(tcp, action, tcp->snd_una, tcp->rcv_nxt, 0); + return; } - if ((tcp_fin) && - (!IS_ENABLED(CONFIG_PROT_TCP_SACK) || - tcp->lost.len <= TCP_OPT_LEN_2)) { - action = action | TCP_FIN | TCP_PUSH | TCP_ACK; - tcp->state = TCP_CLOSE_WAIT; - } else if (tcp_ack) { - action = TCP_DATA; + tcp->time_last_rx = get_timer(0); + + if (tcp_flags & TCP_RST) { + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_set_state(tcp, TCP_CLOSED); + return; } - if (tcp_syn) - action = TCP_ACK + TCP_RST; - else if (tcp_push) - action = action | TCP_PUSH; - break; - case TCP_CLOSE_WAIT: - debug_cond(DEBUG_INT_STATE, "TCP_CLOSE_WAIT (%x)\n", tcp_flags); - action = TCP_DATA; - break; - case TCP_FIN_WAIT_2: - debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_2 (%x)\n", tcp_flags); - if (tcp_ack) { - action = TCP_PUSH | TCP_ACK; - tcp->state = TCP_CLOSED; - puts("\n"); - } else if (tcp_syn) { - action = TCP_DATA; - } else if (tcp_fin) { - action = TCP_DATA; + if (tcp_flags & TCP_SYN) { + tcp_send_packet(tcp, TCP_RST, tcp_ack_num, 0, 0); + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_set_state(tcp, TCP_CLOSED); + return; } - break; - case TCP_FIN_WAIT_1: - debug_cond(DEBUG_INT_STATE, "TCP_FIN_WAIT_1 (%x)\n", tcp_flags); - if (tcp_fin) { - tcp->rcv_nxt++; - action = TCP_ACK | TCP_FIN; - tcp->state = TCP_FIN_WAIT_2; + + if (!(tcp_flags & TCP_ACK)) + return; + + if (tcp_rx_check_ack_num(tcp, tcp_seq_num, tcp_ack_num, + tcp_win_size) == TCP_PACKET_DROP) { + return; } - if (tcp_syn) - action = TCP_RST; - if (tcp_ack) - tcp->state = TCP_CLOSED; - break; - case TCP_CLOSING: - debug_cond(DEBUG_INT_STATE, "TCP_CLOSING (%x)\n", tcp_flags); - if (tcp_ack) { - action = TCP_PUSH; - tcp->state = TCP_CLOSED; - puts("\n"); - } else if (tcp_syn) { - action = TCP_RST; - } else if (tcp_fin) { - action = TCP_DATA; + + if (tcp_rx_user_data(tcp, tcp_seq_num, + ((char *)b) + pkt_len - payload_len, + payload_len) == TCP_PACKET_DROP) { + return; + } + + if (tcp_flags & TCP_FIN) { + tcp->fin_rx = 1; + tcp->fin_rx_seq = tcp_seq_num + payload_len + 1; + tcp_hole(tcp, tcp_seq_num + payload_len, 1); + action = tcp_stream_fin_needed(tcp, tcp->snd_una) | TCP_ACK; + tcp_send_packet(tcp, action, tcp->snd_una, tcp->rcv_nxt, 0); + } + + if (tcp->fin_rx && + tcp->fin_rx_seq == tcp->rcv_nxt) { + /* all rx data were processed */ + switch (tcp->state) { + case TCP_ESTABLISHED: + tcp_stream_set_state(tcp, TCP_LAST_ACK); + tcp_send_packet_with_retry(tcp, TCP_ACK | TCP_FIN, + tcp->snd_nxt, 0, 0); + tcp->snd_nxt++; + break; + + case TCP_FIN_WAIT_1: + if (tcp_ack_num == tcp->snd_nxt) + tcp_stream_set_state(tcp, TCP_CLOSED); + else + tcp_stream_set_state(tcp, TCP_CLOSING); + break; + + case TCP_FIN_WAIT_2: + tcp_stream_set_state(tcp, TCP_CLOSED); + break; + + default: + break; + } + } + + if (tcp->state == TCP_FIN_WAIT_1 && + tcp_stream_fin_needed(tcp, tcp->snd_una)) { + /* all tx data were acknowledged */ + tcp_send_packet_with_retry(tcp, TCP_ACK | TCP_FIN, + tcp->snd_una, 0, 0); } - break; } - return action; } /** @@ -667,9 +1119,6 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) { int tcp_len = pkt_len - IP_HDR_SIZE; u16 tcp_rx_xsum = b->ip.hdr.ip_sum; - u8 tcp_action = TCP_DATA; - u32 tcp_seq_num, tcp_ack_num; - int tcp_hdr_len, payload_len; struct tcp_stream *tcp; struct in_addr src; @@ -713,54 +1162,58 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int pkt_len) if (!tcp) 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; + + tcp = tcp_stream_add(rhost, rport, random_port()); + if (!tcp) + return NULL; - /* 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->iss = tcp_get_start_seq(); + tcp->snd_una = tcp->iss; + tcp->snd_nxt = tcp->iss + 1; - tcp_activity_count++; - if (tcp_activity_count > TCP_ACTIVITY) { - puts("| "); - tcp_activity_count = 0; - } + tcp_stream_set_state(tcp, TCP_SYN_SENT); + tcp_send_packet_with_retry(tcp, TCP_SYN, tcp->snd_una, 0, 0); - 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); + return tcp; +} - (*tcp_packet_handler) (tcp, (uchar *)b + pkt_len - payload_len, - tcp_seq_num, tcp_ack_num, tcp_action, - payload_len); +void tcp_stream_reset(struct tcp_stream *tcp) +{ + if (tcp->state == TCP_CLOSED) + return; - } else if (tcp_action != TCP_DATA) { - debug_cond(DEBUG_DEV_PKT, - "TCP Action (action=%x,Seq=%u,Ack=%u,Pay=%d)\n", - tcp_action, tcp_ack_num, tcp->rcv_nxt, payload_len); - - /* - * Warning: Incoming Ack & Seq sequence numbers are transposed - * here to outgoing Seq & Ack sequence numbers - */ - net_send_tcp_packet(0, tcp->rhost, tcp->rport, tcp->lport, - (tcp_action & (~TCP_PUSH)), - tcp_ack_num, tcp->rcv_nxt); - } + tcp_stream_set_time_handler(tcp, 0, NULL); + tcp_send_packet(tcp, TCP_RST, tcp->snd_una, 0, 0); + tcp_stream_set_status(tcp, TCP_ERR_RST); + tcp_stream_set_state(tcp, TCP_CLOSED); } -struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport) +void tcp_stream_close(struct tcp_stream *tcp) { - return tcp_stream_add(rhost, rport, random_port()); + switch (tcp->state) { + case TCP_SYN_SENT: + tcp_stream_reset(tcp); + break; + case TCP_SYN_RECEIVED: + case TCP_ESTABLISHED: + tcp->fin_tx = 1; + tcp->fin_tx_seq = tcp->snd_nxt; + if (tcp_stream_fin_needed(tcp, tcp->snd_una)) { + /* all tx data were acknowledged */ + tcp_send_packet_with_retry(tcp, TCP_ACK | TCP_FIN, + tcp->snd_una, 0, 0); + } + tcp_stream_set_state(tcp, TCP_FIN_WAIT_1); + tcp->snd_nxt++; + break; + default: + break; + } } diff --git a/net/wget.c b/net/wget.c index ad5db21e97e..74df1378e5d 100644 --- a/net/wget.c +++ b/net/wget.c @@ -21,48 +21,26 @@ DECLARE_GLOBAL_DATA_PTR; /* The default, change with environment variable 'httpdstp' */ #define SERVER_PORT 80 +#define HASHES_PER_LINE 65 + +#define HTTP_MAX_HDR_LEN 2048 + static const char bootfile1[] = "GET "; static const char bootfile3[] = " HTTP/1.0\r\n\r\n"; static const char http_eom[] = "\r\n\r\n"; -static const char http_ok[] = "200"; -static const char content_len[] = "Content-Length"; +static const char http_ok[] = " 200 "; +static const char content_len[] = "Content-Length:"; static const char linefeed[] = "\r\n"; -static int wget_timeout_count; -struct tcp_stream *tcp; - -struct pkt_qd { - uchar *pkt; - unsigned int tcp_seq_num; - unsigned int len; -}; - -/* - * This is a control structure for out of order packets received. - * The actual packet bufers are in the kernel space, and are - * expected to be overwritten by the downloaded image. - */ -#define PKTQ_SZ (PKTBUFSRX / 4) -static struct pkt_qd pkt_q[PKTQ_SZ]; -static int pkt_q_idx; +static struct in_addr web_server_ip; +static unsigned int server_port; static unsigned long content_length; static unsigned int packets; - -static unsigned int initial_data_seq_num; -static unsigned int next_data_seq_num; - -static enum wget_state current_wget_state; +static u32 http_hdr_size; +static int wget_tsize_num_hash; static char *image_url; -static unsigned int wget_timeout = WGET_TIMEOUT; - static enum net_loop_state wget_loop_state; -/* Timeout retry parameters */ -static u8 retry_action; /* actions for TCP retry */ -static unsigned int retry_tcp_ack_num; /* TCP retry acknowledge number*/ -static unsigned int retry_tcp_seq_num; /* TCP retry sequence number */ -static int retry_len; /* TCP retry length */ - static ulong wget_load_size; /** @@ -95,7 +73,6 @@ static int wget_init_load_size(void) static inline int store_block(uchar *src, unsigned int offset, unsigned int len) { ulong store_addr = image_load_addr + offset; - ulong newsize = offset + len; uchar *ptr; if (IS_ENABLED(CONFIG_LMB)) { @@ -116,329 +93,153 @@ static inline int store_block(uchar *src, unsigned int offset, unsigned int 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) { + net_boot_file_size = rx_bytes - http_hdr_size; + show_block_marker(); + return; } -} - -#define PKT_QUEUE_OFFSET 0x20000 -#define PKT_QUEUE_PACKET_SIZE 0x800 -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; + ptr = map_sysmem(image_load_addr, rx_bytes + 1); - pkt[len] = '\0'; - pos = strstr((char *)pkt, http_eom); + saved = ptr[rx_bytes]; + ptr[rx_bytes] = '\0'; + pos = strstr((char *)ptr, http_eom); + ptr[rx_bytes] = saved; 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); + if (rx_bytes < HTTP_MAX_HDR_LEN && + tcp->state == TCP_ESTABLISHED) + goto end; + + 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)) { + 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); - 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; + return len; +} - 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; - } +static u32 tcp_stream_tx(struct tcp_stream *tcp, u32 tx_offs, void *buf, u32 maxlen) +{ + int ret; - 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; - } + if (tx_offs) + return 0; + + ret = snprintf(buf, maxlen, "%s%s%s", bootfile1, image_url, bootfile3); + + return ret; +} + +static int tcp_stream_on_create(struct tcp_stream *tcp) +{ + if (tcp->rhost.s_addr != web_server_ip.s_addr || + tcp->rport != server_port) + return 0; + + tcp->max_retry_count = WGET_RETRY_COUNT; + tcp->initial_timeout = WGET_TIMEOUT; + tcp->on_closed = tcp_stream_on_closed; + tcp->on_rcv_nxt_update = tcp_stream_on_rcv_nxt_update; + tcp->rx = tcp_stream_rx; + tcp->tx = tcp_stream_tx; + + return 1; } #define BLOCKSIZE 512 void wget_start(void) { - struct in_addr web_server_ip; - unsigned int server_port; + struct tcp_stream *tcp; image_url = strchr(net_boot_file_name, ':'); if (image_url > 0) { @@ -486,12 +287,6 @@ void wget_start(void) } } - net_set_timeout_handler(wget_timeout, wget_timeout_handler); - tcp_set_tcp_handler(wget_handler); - - wget_timeout_count = 0; - current_wget_state = WGET_CLOSED; - /* * Zero out server ether to force arp resolution in case * the server ip for the previous u-boot command, for example dns @@ -500,14 +295,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) { + if (!tcp) { + 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 Sat Sep 21 03:43:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988106 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=OFPaRQ1D; 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 4X9ZsG5BWBz1y2P for ; Sat, 21 Sep 2024 13:45:22 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 513B688B1A; Sat, 21 Sep 2024 05:44:18 +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="OFPaRQ1D"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F3AC4887D1; Sat, 21 Sep 2024 05:44:16 +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-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2614::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 EF953889C5 for ; Sat, 21 Sep 2024 05:44:14 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=VfcBaE1TXLLyLvuejpRO9tQmeRi0auFH3EcTMpNTdGnyIFHV+Qsriwj7jFtBpKZy/IMezFiZ0c++ewiRgy/dTEveZA/oQ+nvmv3asCjacDt5UcpdcbM448meDSK2ybhFZNiKp/Lx2PHU3Uk+9yysP2xW+rwwmIjcB/ZZNwrSARgh62x7Ve3CMiiD44f9gd8QIUjwj2fVILobOXDc9xfmL81BMkLFmXIX5khTaBLjvsv6PB5HAx0o6tToAzG3q3sZg/QjZV5HEgG2/VruS/gqUP13/vbjMekq9lBDPwDH3Ufx6U0C9qIcHThCpweHfPSW5b83tUbDIBzi3micuC6Wjg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ZyvxhXWrviJZtOFOZEFqwcZmjyBhsKNwF7Exenqg8GE=; b=EbXT/IOSsOhSuTh01rREcT9tLpqdOAatXg77c7fIK9OgtqF4JiPbHLbdkk+Me3JhnhiMFlhdso5hxNZBhHqZgYGotFrLkyQHmNTVb9sEpIyiSUjUTE7dxYgGh7YPvfcjaEeE8mBWN0ih0d3qD3UZwRtFQtePAnODFkfLlCFpulcm/idAK584AcuYRTgMSgCdoU1xO9pnr1ohcDslwcl49evYdrmljLcX8z3YvcacH/S15cP7s7fRc0dcn/+9VpHhBU3MjZre13iuL0fKrgm0o7UZmXINOOnHUF7LAHM/Cj02aPBeJQyflyru0g4Szpo+1IFwqLBiOcKJCOmgBC4hSQ== 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=ZyvxhXWrviJZtOFOZEFqwcZmjyBhsKNwF7Exenqg8GE=; b=OFPaRQ1DRGTgId2QMfICO8iyJ6W/XL0EysNK0l6oS8HWCdLqydDPtu8z7UAsyxdZpqMQ0MF2NzBE53FDJboavt7fSk7WMBYzMppVC4ke3XMJ/rKbh+F6gxZtX+E/I76ViUvuvpywTPt1MQPF5Aev/AbUO4MsY64nKEkAemBoHqWmFIREXrKulyE3i9IBheCn6umndoaPHitetX9+j7ka8RbCeNeou2aMrnSdQsT6r/38WIe40n2pKnCj3lB4xS9DJsnD6XrAudpB7NRQqdKD1fSza3kF+PwYppklme0N7sVL64MXquqXlnlnBp/vess481+vjFsY/gJ+99UbbY0T0Q== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:13 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:12 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 07/13] test/cmd/wget: fix the test Date: Sat, 21 Sep 2024 06:43:47 +0300 Message-ID: <20240921034353.1298452-8-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: e893033c-836e-4cb5-0331-08dcd9efa7fe X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: q1857N4tql0bXSOP+gD2qUIY4O0Mj9FtCYKypHtfhKCDWxTaxkYHUUf7sZDWBI//PPX0um9zjlaWQiysus8sgtLC3VM6FYnZFDPblGlaqOb7MorFZkhCDVecx/UhAazO159uhRTLYMg4MIDNJkCALYnDghrrciroEKr7tfCAHyzyoMq5u5IXGtaDv6ROSNo2oy3O5l8+MJ10wEbZenaBvXvLDnKQ1Ap1acLr8ot135y7Z14/WapFeigyDGSXBZc+z7qE6/QrrTXWHeKzg2yPvBXsauwhmUEoUmVNsDlm5foD+hj7GC3JDvASNrXfEae32PPHf09T7RTfd3mbVxSqkW4seLkxVnbce8WLbi7BhiSp7Ig3uF6tdmC8oEwtclE8v0jdSC31IefxhnshtAbDw4QKWFgWqrjk6uOmGgmvESbAJVTUWl++PSQ6KqBXPyyL3NKqPbou8ReMaWakrfNCsb5w8scMEx16tP6eQkzRwF8Eu6bgqaZkVMMRofks1Caz0s3fd2R8O6PId5XgkspbmynDrUDcM1pMZImdVrn2chmfL3UuGtaqX9+tc0BD09XE4f+OGNAnPMfxqHOKAE8i65ull1LLYV9KdGysxNHtNPRf/3XCGl5LvTboRQZgv63Fugc6EfchDWrTErbshfyWKDgTOCrakMoc2K6x53Y0637p4UGpqHaRbVjAIAxHzoKg523gbjWDm+rw7zPa1/fMO+y0GRxHOsxv+zScrO8KmhNH7uOa1NP8p65fW7Kja8nIPmncj34Mdui5SDHQqb4FguZD/p9Bko6YT/j/jSpJSaXO3S0ADpNCktGAvyiEkZ3z5rjoBYhuYHtfCGaFg5byxT+1oDm2Z4pXxXMDrzLPTCSodkFHRdNI9s8uU3bvtzMfqmlx4bHh5NR6vM68IcToNfF2ZT2pOOw5DZmJoVakrWLo8jCXaYoN2R4Yg0XbdvdlBrGX5qBBTHn9emgcDyvO9w/si2NJT3jiWwQoePYRITzP+c+Ab1O5y7mfU6yQ6zuaCEXLvrVbIznN7/G2qsHXRu3FKnRod8qS0hBzPB5Pj1MBlq1dCkfEpxouDMYLCmx0YAn5OEwdfk1SKfV2vT4zDgjbLsfyYPILqzrNDOHii9lBm+lutY0T0DNnt/PTyvqtzyPLFZL7Bqg0mZg6RhGxQCmpG7EN+tE01qmo7jZygydJMFeaCWsd7XDqphSzDgEKwTVKMeuzbkmIYcpDOU1a5TdNWvbx5MLRGM7NW4N3cQCYx0DnxTzrkNpjdYrknPUzuJZjddUEGkSqjr6vN7UzN9OtM5X3BVUX+tYoMXxM9kM+knufH3GL9HPzt//fHUUJsnO2eRc7mJCXj/jrXT/GSLnZjxrzcpR7CIZnfdcgJW8= 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: NM1EhPWmyU1m6ppmyVascfYOuPLWhrqcxUZqqc/c6tZwX5Q+fV+cemabxc2EffiLBIfbeoUCXquRJt+FxkylaeAaa9LRAUtyHbOeI5We7DarLwRfbZ7YT2Tt9tc03zuYnjrS80tLv4mosGQawp+HEVWBN9gCL0PM+YC0E9cX+OygAe45GS0WA9moJVNuH6diELQSFuH7QIP+ZTDfpDYcQBnSgK9gK0Gx9BuL5N3SacXQzPTndfQZNSDQvXDka+1ey0L0Iuq21vpmV01Nvh3f60tV89W7oBN5r9oEVSLh+ns/IYYbqWgqaEoSN7gM53EBoYe/u1GSZRqfxhG/39Fz90qLGJ2zsrWjv6O3kb3IvvuHcE2OeIsOmpyKdnWZy1Q4Dz1Tzbeo6NH0O1aI4xZZPdHJFIC8o8Xpy8k4XSq2M6pqedxezOSJQfdLuaD0x7FhDW0H6zCzxyxeRKU1vykOp16WTTMIaz3pBRmSx5fpVafmuyjmK72xQIOwkCumlNQ7bjEdmovU7wWnQRBM3uN/8Xfni9xp+qB2fHk9FdjGoVFrgavkwipa7LL9sym+NMOSig+8A4Zy0fcYjG7cPDCf7BBkxxcxz7DbUy/yXp0pIdXBA+vqzj7XB2ihr7uj2NSAijepL7LYAvi7Qgbb6hW2K0lsuWBV+fvh7IEQENxxvujmmp/goe9NeEZOlyG33RrKU04jpYjhv2uneIrYdbiluoEzz+leNd7IZkbv5/8QRvYndcUVtjYBxNpKs1GnJXOLM8glBkSZ24oKsRCWohdSalCcCeRJGpgRR15VgNCtjlA7FLMPWI/B4HLlwR6ijz2U/uwT/hXuxW1CCQU8Vdl0CIQGbbuJDrnjhi0guBkP5cx+baAvRxB7TNOQhZzmALuunFF2cXVYy40o7T9C3X8GIHlDYgNDWWdX4yWLM1BJxqBAph8TncT/tCe0ImGCbHcx/NPqvbkKf30r+ZUtYFpZivcX6epS2RJSZyszCpEE9nzPh/EBfActd0jAPK1y4FJmywIuIom4KXX5KZZpv4XU1PWF339Bs4miyEgrgzktoR2Xi3jBrcMf2dzqVd7j5lvJz/v6kQUxlIBP5JpvVN92XZ8rLBqQN+0SmJmSmJwS/x5P5CFNjciBzpXrKNziGENK59JxEDHswCA9efsdYW83oMY36hLou4oI8tHEqtqJnptmLCmp3mbwbe0ozCnMouYim7B8ZEpMP4wHYNoCUx9ebjtve58bWxZil6hcVNTSGQcmE5F4fyVyytUFXTY//3wjuGQ5KcjYQAREhist9gtc7AB/OFl9VyTCu8cEZ5Dg17cbX1A63BF7ghOjxJp9BIqwx7virdFjcweRL89bogVFhU+Xfj/T93n3454VP1bLIC/aVT1a3zY0RxJBDtyIVZfn7w7FqS0wCUvhYcyriN4NjbM375Y1o3CgObD8QYsui6J9yBIiLLBdD8qNLlhFoUtsymrhcOGgGZoROPgvjVR3lC/u9Xn3HVxkobjCUEUw08VXMrOl+Hurkr/9AqF0W7F4uWK92s3rgTCuHL16CaebgWPby2+vF24gpeEOi6pL+OebIAZzx7ZA91z745qPpRfTtPFBLmCGHNOrI/qEq1Ees0rS1S1eR/IRiS6eFnRKzHE= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: e893033c-836e-4cb5-0331-08dcd9efa7fe X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:11.9977 (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: Nk1nTY/e59i/HfY2h+NGfsNC2yuF7EvD5FOpcnApcJGLLXbw30eAtSu6WCp80Bd5FQv8BE4KvGqbe9glEmzjO72F18qm8b5/YnvPYfc3WCA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 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 The wget test seriously broken: * Uses zero values for ISS and IRS values (see RFC 9293). * Writes incorrect values to Sequence and Acknowledgment numbers fields of tcp packets. In the real life such packets will break the tcp stream. * The test should fail (see above), but due to buggy old tcp implementation it passes. This patch fix all bugs mentioned above, so the test passes with new and better tcp implementation. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- arch/sandbox/include/asm/eth.h | 4 +++ test/cmd/wget.c | 45 ++++++++++++++++++++++++---------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/arch/sandbox/include/asm/eth.h b/arch/sandbox/include/asm/eth.h index f042a5f3b92..083a7371a3f 100644 --- a/arch/sandbox/include/asm/eth.h +++ b/arch/sandbox/include/asm/eth.h @@ -77,6 +77,8 @@ typedef int sandbox_eth_tx_hand_f(struct udevice *dev, void *pkt, * fake_host_hwaddr - MAC address of mocked machine * fake_host_ipaddr - IP address of mocked machine * disabled - Will not respond + * irs - tcp initial receive sequence + * iss - tcp initial send sequence * recv_packet_buffer - buffers of the packet returned as received * recv_packet_length - lengths of the packet returned as received * recv_packets - number of packets returned @@ -87,6 +89,8 @@ struct eth_sandbox_priv { uchar fake_host_hwaddr[ARP_HLEN]; struct in_addr fake_host_ipaddr; bool disabled; + u32 irs; + u32 iss; uchar * recv_packet_buffer[PKTBUFSRX]; int recv_packet_length[PKTBUFSRX]; int recv_packets; diff --git a/test/cmd/wget.c b/test/cmd/wget.c index 356a4dcd8fa..3e9a5f354fc 100644 --- a/test/cmd/wget.c +++ b/test/cmd/wget.c @@ -26,6 +26,8 @@ #define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4) #define LEN_B_TO_DW(x) ((x) >> 2) +#define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2) + static int sb_arp_handler(struct udevice *dev, void *packet, unsigned int len) { @@ -62,12 +64,14 @@ static int sb_syn_handler(struct udevice *dev, void *packet, eth_send = (void *)priv->recv_packet_buffer[priv->recv_packets]; memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN); memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN); + priv->irs = ntohl(tcp->tcp_seq); + priv->iss = ~priv->irs; /* just to differ from irs */ eth_send->et_protlen = htons(PROT_IP); tcp_send = (void *)eth_send + ETHER_HDR_SIZE; tcp_send->tcp_src = tcp->tcp_dst; tcp_send->tcp_dst = tcp->tcp_src; - tcp_send->tcp_seq = htonl(0); - tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1); + tcp_send->tcp_seq = htonl(priv->iss); + tcp_send->tcp_ack = htonl(priv->irs + 1); tcp_send->tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); tcp_send->tcp_flags = TCP_SYN | TCP_ACK; tcp_send->tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE); @@ -102,6 +106,8 @@ static int sb_ack_handler(struct udevice *dev, void *packet, void *data; int pkt_len; int payload_len = 0; + u32 tcp_seq, tcp_ack; + int tcp_data_len; const char *payload1 = "HTTP/1.1 200 OK\r\n" "Content-Length: 30\r\n\r\n\r\n" "Hi\r\n"; @@ -119,17 +125,32 @@ static int sb_ack_handler(struct udevice *dev, void *packet, tcp_send->tcp_dst = tcp->tcp_src; data = (void *)tcp_send + IP_TCP_HDR_SIZE; - if (ntohl(tcp->tcp_seq) == 1 && ntohl(tcp->tcp_ack) == 1) { - tcp_send->tcp_seq = htonl(ntohl(tcp->tcp_ack)); - tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1); + tcp_seq = ntohl(tcp->tcp_seq) - priv->irs; + tcp_ack = ntohl(tcp->tcp_ack) - priv->iss; + tcp_data_len = len - ETHER_HDR_SIZE - IP_HDR_SIZE - GET_TCP_HDR_LEN_IN_BYTES(tcp->tcp_hlen); + + if (tcp->tcp_flags & TCP_FIN) + tcp_data_len++; + + tcp_send->tcp_seq = htonl(ntohl(tcp->tcp_ack)); + tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + tcp_data_len); + + if (tcp_seq == 1 && tcp_ack == 1) { + if (tcp_data_len == 0) { + /* no data, wait for GET request */ + return -1; + } + + /* reply to GET request */ payload_len = strlen(payload1); memcpy(data, payload1, payload_len); tcp_send->tcp_flags = TCP_ACK; - } else if (ntohl(tcp->tcp_seq) == 2) { - tcp_send->tcp_seq = htonl(ntohl(tcp->tcp_ack)); - tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1); + } else if (tcp_ack == 1 + strlen(payload1)) { payload_len = 0; tcp_send->tcp_flags = TCP_ACK | TCP_FIN; + } else if (tcp_ack == 2 + strlen(payload1)) { + payload_len = 0; + tcp_send->tcp_flags = TCP_ACK; } tcp_send->tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE)); @@ -148,11 +169,9 @@ static int sb_ack_handler(struct udevice *dev, void *packet, pkt_len, IPPROTO_TCP); - if (ntohl(tcp->tcp_seq) == 1 || ntohl(tcp->tcp_seq) == 2) { - priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + IP_TCP_HDR_SIZE + payload_len; - ++priv->recv_packets; - } + priv->recv_packet_length[priv->recv_packets] = + ETHER_HDR_SIZE + IP_TCP_HDR_SIZE + payload_len; + ++priv->recv_packets; return 0; } From patchwork Sat Sep 21 03:43:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988108 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=QusjNweJ; 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 4X9Zsj2PQyz1y2P for ; Sat, 21 Sep 2024 13:45:45 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 44A9388B58; Sat, 21 Sep 2024 05:44:20 +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="QusjNweJ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0386888581; Sat, 21 Sep 2024 05:44:19 +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-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2614::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 82197889ED for ; Sat, 21 Sep 2024 05:44:15 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=djT7vI+1EaimhDeaaU80ym08/kgN48oQHjXOqVVGVjED51NGhcqCUPoIeh+ezZTKRkegQ1TLdK3QmXsM+wyp3OkIdxbfikiU6P/fsQUt+OAq407hPEjFnCLN5RiyqKtQHkPZu/rhXgHZoqEGMraVAtGKyahCdK2m0wHjo/G0ol5L3wmdGgyUH72ETiOCrCe32Xa+g3JB4VqjBUvy8LQ56HzZiorHJAAycqjxZDvKaBZySqt62dBhYdVHCgpQQ5RDQPpzrvPCJbidUvYodWNapUHsMoMyT40SuP6tG1RWpIAtVR6MazU5D6gx0yudSdP6oXMfadQIItsAPbNYHvurGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=6ra4koE7FMt8V4lStDoTUBZocdcVuScdpfOigsSqTww=; b=ms1fvUBPYMxOcaVFFd72GuSbhZmcEP5hLm4qVwIC8dhW1d3QJDxRPyhQABmM07DoFXTAAeC5YKYpingoFnBCl2SfmemFSjdF42pXwqMmLvfbkphW6RRZfNOHTmBjRzoJu1YPl5PEK75NlskGnx+Db2ZfDyR4A6E97piCGbP7cDHzw09hhsbb0tQ7hpTxELPtngnR2Z8MLz8ZGv/ulIaNzNHeU/Mpm6XH8MZVNmlXo7faIOWMfcpjdalgiAu6owSz3oC4tFT+zkhtGtkpyyoMKt6D+COd/b0tZX5eMe902/Et1ZOgaogVxbar6sNEIKeE0I6n8ZBuImHToBVq4TvhBw== 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=6ra4koE7FMt8V4lStDoTUBZocdcVuScdpfOigsSqTww=; b=QusjNweJ5POS0cMmD/mQdg75DNr/tbWa/npUK6zK+MCd1DGK8IopJHcVLbftZ2Da9m6smiHZpyGnXxVuQDaniR+Q7lGtEOnrZX5u2sgKJ7i87taBbWzv6WXAb4lYy8DSaPhbJmHXd7r7RghR0mpw7sKhOVrKPGrXziUOv840YRI7VlCD0MHewxx/TCRaI6jo+c1rB/pS3rVw7oWogfgueHD3gPxYXwPL4LixYgAy68Yxs4D5oVohsEiYzcQ+wZvgKeE/K/ueMqLPB7nJtCVLlifhKGAQfIn3BnB6jhWgyH7DBRu8JQN9PbJnu4nhm19u9lphFqdo8ALNEgos1gILhg== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:13 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:13 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 08/13] net/tcp: simplify tcp header filling code Date: Sat, 21 Sep 2024 06:43:48 +0300 Message-ID: <20240921034353.1298452-9-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: 9f9e4873-a657-46f4-a0be-08dcd9efa8d3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: J9fLf3wuMpk1yUM7ISSP9jVb0wtBW58jAg3HjH+NqGTWFQjIFqbNXQVUgRYGmRUjMRJ+kw0VpA3xRtqJaIM/RegYLM0PLzJjgusXXbufcxeeWID/0hWUGtPG80cn3haIZTau03MjblNwrtBAd29x9wq+WR9YhhoOrEjCTMgiIDjEKlgmHDvVRZ60rO7LzMesBxDOWRD8QaCviBKfOHafH2nBHfjH5fY6drlbWcjI24u/6va3qEkjPCw7yTwMzYukqD6phVlOSez25puEDEplwuIkWp57r7PilDRUplNp0i9XnFVkE0Mi3f5hf3oqWSlW9+FVh5/mNZBN61raxs98BXlH+WGodOt+ENs61HpdSTAYLQPwxM4lrcU0jpqZUr1USPN8hF6Pav30CJ8aSEPGWNC9IqtSE8YF3XGMSeAb8B+KAfFUJ8pc+j/QiKsOXb92eAf1Zwh0p/piQvWYx4t1Tpfaw8gRPHK5feP/k1CN379jPFqHrgFD+1c+EvBgor2/7HdblWyhYBBY9Ag1YOkbef95YnxmCwySOL8LdHCBuazrxMvZC2iV8bXfPVZMI8tbrnrRaXdfc+u3sVekJq7HWTDoFwvQAkrVXuc5KZ9teiISoeiE/MO/68xejT2RZ0gSJ44HYFZbu2uoiicIU5avVqlyok4AvmFJ9HftRLMMqi0uJ3KAG323nkCASd8sRThM23kWUtKCA81t1m1hAmE9jLHlBm0lf++8O70FHekpm59+zsTXzlc2/IAi/nl2cy2uSSYGXqU0hgmWEmPw0Z+wPz9pyx1SiwFAmLkeeuVMIoAVroSFq7TyrjSzqUhvM0lK1tmy8/GST4blmZOKKqRZ05ha+G1YsgFoWet5WAQDTCO88TYonHgWceC9EhUFv9JlGCY7Mw4SQ9SjM2dBa8yaucg6yCAe+i+9bdp2YRCjpEzO+JpxuqkxCr0NydfAvTjhpmDS3w5RAIaVBdcBGTGqQQb3UA0HoLgZvoNUGmO+sts44f7/WYTYa89XMeL7zVcZ0+M2P9qwBFe1a9Cxc5kx4OKZrBRn3acPBEvj1lxXbvVulszugni9feuKholjwiQrg7bwotqUi6dP6g80O4H+XW4jiSIbYpsHpYbo0VWVGPkMx5tPCYO8noWBWveDgsE+VPwd7bkXB0s3QDeRBENQZfp6YH2IKhVIoqH0bdrPq/YV37rTUeyrWYOGVqywtHyEIUWgOnBoctSd+lNhQzLyyzN8/LlhN/VH+ZvSVVC1CmlWWIhUc+lb6rkz8G3pH66FR+lBUHf9b9z5jMpym3Ozg5u4gPcKXYL3fmuUDc7nxwtPwt6/of3FFNRhHMbVp12gYp0f7c8/bWw17TW+ixhwyQ== 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: YludcZPvhDWMToOuvV452DQOK+FyTHXylzFFU+dXSTmUEeO/IzecDNj8aaXYrMsmp4oSArc1hHK6hi9xIBB5LhLi0cgT+ZKxgz4XxPfWtgKlrtEJXi6wuR/RieCbI6Qe9g5QWTVRAqvScdeAJ+dIfgO5uo9nIrLfGQWHERgb9u4tsV7gQ6Ip9lTqzGoGZGBAU01Yl7HMPgkj7XGIy0iMJHL39eBAmU5dl2kthmHxHXbAuDsULOysbzeWcS7pbqtlVvCaeFe5lhFksS8AmX7Ib1VOtVWoCyKeJN0mhgub/79t9VK3qpl2JuU4pBfoqStC2U1wq10fcv97ncT2DvP5Bch4dLB6XY5sBBf3VbF1VEajyxrScUDcuDQ0XQjlKnEYhOxqHw7wLOVNahf0KS+c8xcCzVbjAFjPZngqlxr4saJgqAFyhAa8gNQfR2H+QdMvcUtsahzlnBx1nuUgSswcVn+HSFTJpyiEvijlswHlWLRh9YPAxDuVwC9r5/SVuVPWSuleULDVHVrkMSumavJAZ+np6nye6Io7eJcIqdJgbYXuA54LfdHOrRNzUMmbzte5uxVWdKXQq1HnCG7wKMYXCgOpunob42owzNXSWiwJoVuiGNfZqC95qOEaEoEZ2NZFoH7zXhpRpB/1qjJGKD05U186A5Gli05bu5VzcT/Yuu+hfffwz5aYatLU37EppGoRhZbczak8TleTwF2UDN7kgQCUJywrgZs+fTu6vtxrup58+38LnZ2TPn9/Oxtoa9A3P5oF7ROhJy/ZFp8/m83FIQFW2I+t56joIMrpr9pc6cuZ4PGMIktr8B3YymJMp5T/IygHvnBfXTp7R28CsnR0Lij1LCbRPQUpwwUd9Z24mOPxBKXcPSaxf54r4MhKMsW4QcPOElclD21n1QiR5Dc2jbRzeJNQoU5QuxqxEQiG+2fGVeDj/xav/YhUMajd0b1K7WVL+I6GVUiHX44B0vrLP2dcNh6VCCK+f3Ck/e2DT/eQoQwXyAR+vql/qstJMj6OcocOQ9CS7roZRHcacetVSPaytKwD03lSswgKT91drSC6499SyL47b9SaQQdQl6y2Pnx2U7RBZgVpxZnnVD756hU1fAcoOaHcQVXFsBYRZ16TVD/HlULatMjHLXCr3R+L5q/QOTjQHYngurjrS0nfC3wz6/ndgnJX6kOfbGtIXuiTkACm7OgyAl3uIF5a3TiNsuwqWX2qzrbraq7DYPHBwceqkUpyUC58Qo61EP+zYoIUaaAMAfab5Gxp+l6/R//bW8uYa6QL4hDO5yZ1Ge7wVPF85d9zMs593byS3AT4KqZYLdn1zQKx7lt1THrbApTzxgVZ74RYIHA2jw+4NRZ/XxmgvBFzuieQophW2pY1VNpmXu5YYKgwI0sTH1yYlFTCUi7rmJPdNBn1HOqhAryq1DkQISgHjJ6GPQE843TiCfTDNJGpeMx6BQCQq5Gs/cfo0I+Tx9XnR625xJb4Bn6Cehn/vhsKklnYjwlq2ENYLIF/yKVfXNrzdmcutES/YIv+wTjjluHkioKZfiScTsm3z8bZ3YdMcajks3iua6MhS+YryFoR0foSgCHq0YQgRF8qQOZaVinFM6brAmXbu2iyoRnuxLw/4iGWXosIo3po6Ms= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 9f9e4873-a657-46f4-a0be-08dcd9efa8d3 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:13.3950 (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: u/1BSWG9lyMNE5EVKSHFsRsTTWXn68X0/NzElyt5aYcc7jfrib7O1+BlTOuH7z9iZIV5j6dL2oQ5eFzpld4ziF07I41fsPaqhZ5Z/VxeTkg= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 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: * remove useless code, * use a special function for pretty printing of tcp flags, * simplify the code The behavior should not be changed. Signed-off-by: Mikhail Kshevetskiy --- net/tcp.c | 66 +++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/net/tcp.c b/net/tcp.c index 07c57d3ea8b..647454fc064 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -537,10 +537,33 @@ 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; + static const struct { + int bit; + const char *name; + } desc[] = {{TCP_RST, "RST"}, {TCP_SYN, "SYN"}, {TCP_PUSH, "PSH"}, + {TCP_FIN, "FIN"}, {TCP_ACK, "ACK"}}; + + *buf = '\0'; + for (i = 0; i < ARRAY_SIZE(desc); i++) { + if (!(tcpflags & desc[i].bit)) + continue; + + if (*buf) + strlcat(buf, ",", size); + strlcat(buf, desc[i].name, size); + } + + return buf; +} + 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; @@ -550,55 +573,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 Sat Sep 21 03:43:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988109 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=zpPM9xOy; 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 4X9Zsv6J8Vz1y2P for ; Sat, 21 Sep 2024 13:45:55 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D5D02884DB; Sat, 21 Sep 2024 05:44:24 +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="zpPM9xOy"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 92ED4884DB; Sat, 21 Sep 2024 05:44:22 +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-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2614::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 13BCB88AB2 for ; Sat, 21 Sep 2024 05:44:16 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Fv7nfGpojk7SSetMPMCQbrwXlvOd1M38ahtyuM1R8u2hJk8MAazyI1eAVfWZ41BOWh4mqD+u+IzJHdaP5MQPL/JGSxfMZq1zC2ZFM7/X0CEewluitmvSvGkbRo59CHti/qOPqXX3xPvdS48TulM0RxjPuNSsqmzpf8SLA/fMrx1QIK3FVq72vlrIVMfkVG5G/kRIAj0/G7DqkEQpNa5PYdU8W2zfYOBZJH8LpMOnap+Z5clkjyNZGYp0JM6ZunQ3iP5tdKcdWcVOSTwfQwVKJwLd8hUEGO70CMhc1FHh5xBdG6bCoALtzR0yEqIvH1CCYYs+zlaXlbwZ6RbDo9Yj0Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=PL2WUbdpCCdF0Atc32EvM/rgoTAIppaLvvQCD+Qk3xo=; b=su1ZfH2deaBkH5n2xJOi7HPANsEXlvujo8dRaGtkDlhpxH+p4jgBVGvd2p15Uo8mREYGdApy/DM0bbtCutU43fY7g0LmSCOwBDtRTyeG+jbOxEzQpSgnb0i6+3En5QT0Q26ln5sBUZjI1zBcqYE0KOdQqVTQIBUKK0ugN3EhsXi+IvubwujFbUSSV58ACNJe3djcagDw06wxCFEUqUWGWY/XM9U5r8zdjls3wqqz6tT8peQNlnDGTxaRw4X+fovo/znnfgBvqL6wElyeJNeFXdNMYW5z26vavIwTgkXYZUEYGWLR+beAFk3YFYAynv2gpaLVu1ndid7wbek2nnLZ4Q== 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=PL2WUbdpCCdF0Atc32EvM/rgoTAIppaLvvQCD+Qk3xo=; b=zpPM9xOyJlZMVXuiYm2+9eAsNfJQpz57d6YYvkMafLlljWos0Vw9eM6pLNJAULrfKduvC5B6t0sa6UeZWLeRh7uJg5SzbN8D5jxtSnX6CGJoUG9DK+EM8M4pj8ypixIugNb6BP90Ayq+GyWHuMjXTnA5FgahB/gTCn3I97Ix4N/7+kaSIA5ThH69bLctKXSz/Xyu2duVy6xDqSBBVfVaKO/ZuyAd4WU4MP6aNB+cryXrpmNArF6Z12GVfx7eGdzLr4eVy50j9BhLC0EvoEE4qJqYkS/fkkjrz5O5Ne87FsSbUjz/EVSfLF/53VugKBqfn5GlLLTeM3kpFWv/ih45yA== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:14 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:14 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 09/13] net/tcp: define a fallback value for rcv_wnd size Date: Sat, 21 Sep 2024 06:43:49 +0300 Message-ID: <20240921034353.1298452-10-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: 92f74c5f-71af-43e0-5170-08dcd9efa9a8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: 35XUjoCyBaN5imGnEc6E2ZW2ajwl5YWI+QKyJZXuV2Qe7TbYahoBuns9LwDQP2xSteMZx5VZcSL8R0rH1LJH44IkYIiOQXeJScevEePIC5pqcf8LNYk10w2ye6xXwvboxILXqtGqBmZxp2EUMVK31KwiuIORZFRAZxFX0BEyYuG4h+DiwY6yTNVjC6cvefbKrUQaM9yZymK6GMEXzZ/NeqMIVsx4ugOSLpR6Kl22Mxu5pguwNJ2Wk9tPcF8mqbBa0cgzI++zRXnzD+0gJDETOGrz9qE8W8cmYJb0tU8Roai20yVB4OzfVQ9sodysq7+KP+dwquok3c8ui10UhCx0V/tAGS4olfj2iNZ+QYQvG3OhG82VbOCD8a3/VzzDnTOy0tNxl93pFKZ9i4iUZHr22wzARVvQnpwxmFV0H4ncqg2TUqVqVbw2c5V2oK9r7+0BgPUzkYPg2DpK24SfS+TPCjiLMpARjTtH+NfDWlUkOoVrc+qtYyHx2YOM/mA0C84WvMh7E/Wkn9ooYuudk59Xak5ghBj0FRg8VWQ440YqdhzWQ4/e06tQ73CuMLb/58y4XuSgTmOKV5d9VwPlsEhxvyjikR2WVNZM3uAjjdTqCIu0TVha+KiguUIjP7ohSYCDcLCsXJUsN+Hs+HoR1GV7Ve0JAQObnWwhfvJl2Lz+SwMPOpGtbyb7K3zU0jcVn8prDEHDx/R0v7SNgyP+5QHplbWPRlZWAvfq4oAYo68UR8Rk6Db+Hl3FpuyKSy9gRzgwm+Jng0fr8qFJGP5D6b5I9NaMxsjt9ivZp/M05YrMzeRy4ZIHYMCzFyxFK8cOiTxHCEFI6djJA9shh6HzZCvNxqUEOLeXaOZ4bu5s/PS+n3G1KN2nvQasAvZhYtzgWjkXMkDdy39fNMbhGeinr61MOOjWB6qYjS5mEx8ZQtnXPnySg5IHIg6mKj/PnKa2KnLwtgAPhpMaT6g1s6sCDM1MmJUjDW4M44xijUQ2nRSqCTxECY8DsZGbx6G5el8ahSD3smldWMb11aW1p4xSZGAi6uuzeJGvgBIgKqttLBdWRgUlvTAxziYy30WBMy2A2m7tPaL6xw6WS9AJAulMqn7wlwbzvOY70RyjJIqr0SFx/oh/rch8cJuepnsasIXPDq89sX/f8Jfj009YhnTMud1rw95MaJsdYMKTDS3Z4YHJuTfoyN3m/cIgXly2CmAdumeCSqhiDYUlFdNZILxDDVl/hG6PMLKhGAYH7+freqS7O783FBM/m+mDDPpKp4S37q+YHMYmrNWtcD0a6YAgvSsFYtxJRivqhkrKcQkr7WIwLLkQ+Dhm45IYWSCQRrdvOOWyqnY7H6uSGhGNeFa62t0E2ngDmiO41RZmwTjw/aldkl8= 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: tbZpQNydU1Jvw4+5ZbBftZ86vKtE+pTO8KunP7zIDeHPMBoC7Xj9Ly20sayEOdXzRQMcVMing3xA2y4KkWXA2LFAnHwUvorceTCd438Txpvcu78xgUQV3v7WDJjnOQy3eKrXtiW9KFzgj+8HrpTqGjfHWkB21kh7+DfAEr+siKCULrsiX8j9DjoFGexowtHl+DK3cSI/u6kcFI+1niYDARonBmavPxroTCwQyGHc/52fp4t1MVdoFMhFFZcaIngSMD4vUpjoydAyPxFRzdfHgr5E6Tal9QNYfvt8SYAmZX5G2dtRjA/zYYv34OIQaLBmebg1Hl7VAwt1R1dC8IPwFvzFLt9YBVsIHaWP+V9fRPtmp+eaNsgoGWxrGSlrfvV+Qvg1LcHJSOk1DH48QxCzppSi5qrPYdgWeL6cz4sA/wQKAh9gL+pTC/ByfTM7HzKwZ099I0whtakaZmkcnYuCFG7lEDuTUsu9XXstMnxx0U+nUZCVZEq9Nyu1YSEEltGf/mDQrIDVaFZkILhPZnDwsPEeLj34APMySmMQSjIkeITi4OE+FWlIQLqmTNLq027z8mkCQhxfVKjDvpXIS7MlRcWLtz80SNmX7S6rdLh5yj+SxbPvn2rN6x8Nf9+poDuPPNcDVscmwm7T2qor1zG2ut60C09boKYQCuGPe1Rnqey8GmpYS+XATVwjurTv4ugaTtBEt6k8fXbFCdwbGpVJnhuLY5DNcH5yO2MZiVTMaLCNaVNZnOv0yC6gq1bACP0/pXrWkEriP5/k8u0v3zMFtxZCvBcjXA/NHVQxKdtyERxM070JZ07hUy4UE/G9V0sPMZzn6xOKfVoW7GVTxoaRn7e40PU2H1Q0rrYdsEdwn375JArroqDrlhdxJAHlXbhQka0RCj3YTvLqpAv5xwrzNsf5z6yXnH89C2ctIKiiL6/Vm0PPShFjoTk2+Eq5hDN7Wan/Du+ygI2A0IiMFtLoYLWUOEE979c5vFVkFDtR0649S4R1zB9vY3zAAiX3Y4mTUmJHHCIccC8FVj/6HimVigbnIhsYI+wZFnjjya/n1LRrr+ewHuCIyKSipNAGmlzrfoYrZmduFNhy91UsRd2DCS277V0hR4Keyby/ya5dL8NFHyV9I+6zxyY4vdDTYHz+JagTnILefPc+uGbnku2ob+2VJYhveB7m7TyXJkSb+2EU6lTdHpz4opMJR7Rmm3cJha92Y5gk/zRgk8aOnNBJmaJ83g6ySSkpL2+3SaibN6c/qWfO4fpak+WSB2LxiZDRBldCBFHsNsgmc40yCE0pgZXjCxt1P/jUkGDfW/F7TydtkuWsS/hDvcMFw1sOghvGM+XQdTWBYjua/Ze8IuYl6NZS51pgz8ggtI2wa889UtBMH/eNj/B7BBr7kZyiJUIw6SgECbwzTK9QUxBR5Lokg6B0iHozCiL7qPKWhC8vuTvn+chWpL5AiOaJ38nETRR2zCmBRpW/d1/kQDsAj7hN+WMooV5y1w0KU8gwVv9OlSuPUnRV9aBdVnt6K5A7hFJE8t0h6ct/VQQg+8R/RyRY82QmDJ8sWNWadMU9dTdaQBhyXaH8tkrTsOE5iecljU5xdN9DsgeQoVzzegRrU6HyjGBQEi0NpaxdJ9t8DCt1ysw= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 92f74c5f-71af-43e0-5170-08dcd9efa9a8 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:14.7859 (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: cZV5mPPfIXNkwW89WvqsTOv1ZiwT214HTNlnvPMpi3H1B+jKsuUcDf6Ob+Nu5jRxxo5cP/V0IHs+iN/roOx9fBd2QJoiPxe05z4yj8iQCNY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Some driver implements it's own network packet pool, so PKTBUFSRX is zero. This results in zero-size TCP receive window, so data transfer doesn't work. Avoid it by setting a reasonable fallback value. Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- net/tcp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/tcp.c b/net/tcp.c index 647454fc064..90f2ee1f5f7 100644 --- a/net/tcp.c +++ b/net/tcp.c @@ -36,7 +36,11 @@ #define TCP_SEND_RETRY 3 #define TCP_SEND_TIMEOUT 2000UL #define TCP_RX_INACTIVE_TIMEOUT 30000UL -#define TCP_RCV_WND_SIZE (PKTBUFSRX * TCP_MSS) +#if PKTBUFSRX != 0 + #define TCP_RCV_WND_SIZE (PKTBUFSRX * TCP_MSS) +#else + #define TCP_RCV_WND_SIZE (4 * TCP_MSS) +#endif #define TCP_PACKET_OK 0 #define TCP_PACKET_DROP 1 From patchwork Sat Sep 21 03:43:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988110 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=litGhO3t; 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 4X9Zt70JhDz1y2P for ; Sat, 21 Sep 2024 13:46:07 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id A2C73889AA; Sat, 21 Sep 2024 05:44:25 +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="litGhO3t"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0D4D1884DB; Sat, 21 Sep 2024 05:44:23 +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-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on20700.outbound.protection.outlook.com [IPv6:2a01:111:f403:2614::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 84F8A88AB9 for ; Sat, 21 Sep 2024 05:44:17 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=b4sShYR5NA6c6GKUGslHLI1HQ0pKA0zie8picwMSP3E4mk4yK1UrUo5J/HP9WKdtLGyylyKneEbKKMVPJhf6sYwwCyJhW18cSQCpvhrc3yKWFfEqXEPQj10ufGvh3GCb5XMZZRlxod2TZ42V6xrnQlskPjAPxkMAAniA/oxV1cnQefivTwpC560OE0miBUiP/4sWgfAlGLOLleKJ++tNKhS1H75XsSr9ujIeHLURO5nVixylX9MKHusU1u3Sqx1Mq6TD+HgeLNn38RDetRnOlijegnn88S0beW3Fher3Fvk6ZuS0/L10cUOyNdznZ3ysagBWjmDHJT5QDuFZwI3aVQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RmjXGSawNZLXUktFdcznmMLK4L+4znp39pnky4x2cAc=; b=kKL5Qa/VH3o+DifNV8Mruk5UHSWQQFEiIMANygIERFSVPmi+oGBxsBKNVpTqaNzoYxVo+T1k8BX66EgQ6sP6lTSXYUmHcKwWt8AyXnS/Zxo/MQ4Tc2XJfGjV/GqfaQOdc1ojr1RizJz07PzRWGKrnSihZ+Xd8GUWALjtStnufOjJR4KWPiwYnRKfriqTZ6Z3csZdrCAO9SAnl+eMPD+B2KQLjk2IcrblIlwy+IHuGaIV2a8WUJvBilJJdBam3gD+SFA4jgIOGoDgQRw4e2ABh7/MhQfGw6bGItKNKEvtwKciZvjJ7TwxfPEYkC9bjnsMzh9c9wGUz2C3nkLAF2kDLQ== 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=RmjXGSawNZLXUktFdcznmMLK4L+4znp39pnky4x2cAc=; b=litGhO3tNC0FiZBlQpfv8UoFFAU7RpnUvKynqlUK1tKNAv/nBp6HcyS4o6unospXkf8yuANNJ2GTNxF1Bx8FBpuo3H05m4j197Mm2xySoryYy4/Opog03pq+qsFA071hrPGEtePf1FBgBn04eFAJ/50oLZFjTTMFRHEtYHgKC82SypP9nx/uokeAZ5a9iaX+VrteV5l3GiNfo24+63WhJBAI34ZXzmxDc/ONVzxvk+cMHCZyAwBpHxZ8ScH9W/KwJMITNf6yaYOyHStmOfKuHgoYQiXQ4tFCoSyHp0d31aSQ8jTrhswM0fTVGSJjr2/lUHLOZOTwOOa2qEPpCS3ssQ== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:16 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:16 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 10/13] net/net: fix include ordering Date: Sat, 21 Sep 2024 06:43:50 +0300 Message-ID: <20240921034353.1298452-11-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: 5cbbe481-1c48-43df-3a53-08dcd9efaa7c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: 80BZcRAzROFFdezRYDdpmlm/RFXGL98WKtriO1V1OVsmuPAt1eCEDr8KCtsU0c3irrpPQjBrFW4q9yIF9JG1/EukqR+HnyEA87F/ufFqo4yMA8ITVrFaNdyC6NixZP/TTd639XYusCNi9mciTh8+9ekporouXyoQNNfT+OKysMDPwkMH3ZF2/z70xQlAdN9QHdSvH0wRd+CIvdfECCqNRZvRWRE+lb28VT3y5T9upUGyWoPHI7skmGHx1EfHICD61Ezl/TZfs9cNugw5LrT3YyaDWYZR4e5S4nNK2l0vQfFoK/1pKLb1SU6gCLAzJQvhZi0gobSQy7IWEJGROzyckYaA+bGBqBN7/the5/WAtSyHQTJibcoX8mDOlU28uENSevepM5/wYFgMvUDcpon3cjqtsl3ggdOYl8HH88uXwpXmlbBCOjDCoAlLPyc6XlxOm6n4k71EeQ7whH+A0wg0eYVopin/3VlMrnNGf0X7smqdpxXkaNWvrCfFVjagBi/KCtJp6/C4houwSJnoeLsF3YptENm5tlRbLPFRbwAAKVtjYRYXz9zybg4h11Gp2SoyWOTQI++/WAToEesa59gTy8PAAGv5SQEvlM2Iy/vLomAEO6RZX+/XnrNrtlOSRN+vl1JS7JF/JjjthmRUftTlrl+fnePhneIa/ES/JfLYnAxJgDf3kc/Qy7JX4bkopNr+eDDuO2Qt3TCOkagPgpJQ1DBVj39rrwbLZPq1IuXiCRry/PkU2jNgXcgogcI+/0Nw486Kd6fGfzAPev+zL99O8vtSX+Jr6FHxK4vB6IvsTbj9RYKsrSetRbnoqvDWL/rs91SsO/xKEUVuRngIidXphXY2OMhm2f9pGln3LOZjVUY7qS8hMjKnWexUIPWpime7/EuMgw9UR+rn3vzss1XdLu1D3rLh4aBgGPdJ0ke7mgouKfn8NLZUvfAhA4W5sYQdrW48S7s+CFwi+pvuGrlbzW/5JGUJ8h3sJpksbBL7ATtCwgPFernwcpC/XaIo5ZA0/b7kBgqfuF7DcpI60eg2H64asJYAB1yc+jKzyUIYz2RLCc/pjK9ot1mj5LI7StBOp0rIsVX34sG6v7zXVB/w268nJ95CkXViMY0evtN/uq//EwEQTSrykr+UaEXnKWqmc9T1P2cFLbrDyiRIAZxIjgor2LZjCgy0g1Q3MSxhkcIm328clZcrUHF5b6eMPkpHKwicnQcfLLrQ+XaF4F5mwrtPF7R3QaJUBw/ptapqxg93x/juplPOMEk3L1SuMB8Gu1QH1/xJYnGU0ErKksDTD2dVFCNgmoNKTinBJ5HxfpA= 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: wCfkecGMX/aELJ3zTySFXRIJGip8jWizFMnmWlCXKgoAaYZ6OVqId9zhhU6W1hpu/I5/LaUuZAQ+TpcZx/Nno8fguswmvMg3dKU4zPTTXSmgk8b2lTfaSAV5eyELAK2O/1huX65TKRgpRZOyelyeRzWFJTlYZYUt2+SMe2ii0ko7VyXdHjeHubdk6YU5mQHSmCvCHt5T8b8PWWbRalF/+qYBSK5J+EQY7n0YTNv8gg9whvmAJXlCLkgbEQbLUWu3DxfOja3xTjqbD1uReFth1uBBVrspvRRIi51/pDlnqoF10cFfm7BJ9RSoSJs/qvVfCyb8dA8U4yw+16k9gz5ONU8ZAjIgFrnGFDHO61b6s00qN9AzeDyZn0HLh0OsZmhrR27ZqTkOHAGlgv/soEimpk5p/RmA7lJlZ+XgghP1RgaHvlJzF0GFL1Ma9TVTc7a9ZvVAbyuiuOXFM1lvNaMAxXn4gYW5XLzCRQ0nUxCLNrigBDF9LImVNE5uig4TaU1BMF2trhJpQZE27h83Vss8Pgp0XUaeMWRY7+CRjz6cTjrzJ9e/OmCM9lU43AjF5zvlrvdn5HX7ZtaM+oA8zdDvsCJTTQ3+/zxjBRlU1c3mrD6dBu4XH+Ni1jIeAZcMUe2pFPZdumH5j6YG1/e+XW3QweW4MxfldPNLru0KiyfbLMSaLyJdvDZ9RPhVVAmjXtWOJ3zklyLJmgNnWYwxquJxSHoxDRFUgzJ7Fe1UeEfhapeAjou1WhVcQXAmI5kJvsqe05+acwH8qQ9874YWP7iKP8bgyv8wjkfaS0Rbxt9AJ9/181jhX6PleK2O6awy7cGAMGDAK5bM9XxkNGXeYI9LGPiNDIuv3xoOugMFPDG1FDf/cHRbigLbIPhawCvD/yZ5QgEmM0Wq++dlhF6giOHfjOyhkkCkH8fD5s+gQa4m9LJdVmyBUUKUutXMkmgeTskq2tNyVHJMpo3GlXBzoiF9QQvoHl2EYHu3a0ag3Cw4UJQ16RpebzZt4XsrUuZolCJTjyz2WiawmV7r61rwnm2x4IFKDdYr/d2/A+Xi05vrE34MR8rrxEvfG5+RojJPzuYojJY4823m+T60T2v9ptHiiyG8/25bk5H0bD7BUui+R1k0OaS/uFL67ugxQeJL/abJDD/ca4cFX4m2PQNtxOdSAOELNj/YknaLw8w58qL4rhzCcL2krScQKDMx62LUyXMqYSOol0RPV0/2uwoufF5nNel+5d6LCVsg7vrJCbcSzZqfUHmqvGeMk/PQp18CSTTuwH784U33Q5HFp6t4UfW4TFTvXt3sv/b1DXFRmgAlTe9pfn5w56rc2+X10syo9zKxVXsECIhYrzX0fh2dj0dURv0P8iig8ry5tHvDArePsVM6sSsuH+m9CIq707JuPjwJT/OmALvPwWMKa2xFb0Zq4ohHx2fW06DWaGDmCS5oyAzk8CiMmH6pnpOLAjVC3YlLDr6tn5yhjmEQ0Yf3u7rwuvjMGrZryQbesyq+AGUK3rKBFjJXS4r18wyDbjKkh5YRYBt5SdqrlO+7YXibp98nJzzevHR/vN6eKDScnL6yvIGOj/fIhBjSbcCjE0BdWF3KtCZWsOeFzmJGJSg2HBhNRcof8zfO8bnvKhd6NG2raVc= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 5cbbe481-1c48-43df-3a53-08dcd9efaa7c X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:16.2094 (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: xzwmlRrKJstro1j0KmpSOCSF9ZfIdFbtXsmbUgmGgurJE8ICW6pAuYLX5iIG+oGu4hAl6k+2r398qIvjK+d6i9MxOr91Y/Hd1Ejs3AJc2j0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 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 fix include ordering to follow https://docs.u-boot.org/en/latest/develop/codingstyle.html#include-files Signed-off-by: Mikhail Kshevetskiy --- net/net.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/net/net.c b/net/net.c index 86182cc504e..92156b5058b 100644 --- a/net/net.c +++ b/net/net.c @@ -88,41 +88,43 @@ #include #include #include +#if defined(CONFIG_LED_STATUS) +#include +#endif #include #include #include +#if defined(CONFIG_LED_STATUS) +#include +#endif +#include +#include #include #include -#include #include #if defined(CONFIG_CMD_PCAP) #include #endif -#include -#if defined(CONFIG_LED_STATUS) -#include -#include -#endif -#include -#include -#include #include +#include +#include #include +#include #include "arp.h" #include "bootp.h" #include "cdp.h" +#include "dhcpv6.h" #if defined(CONFIG_CMD_DNS) #include "dns.h" #endif #include "link_local.h" +#include "net_rand.h" #include "nfs.h" #include "ping.h" #include "rarp.h" #if defined(CONFIG_CMD_WOL) #include "wol.h" #endif -#include "dhcpv6.h" -#include "net_rand.h" /** BOOTP EXTENTIONS **/ From patchwork Sat Sep 21 03:43:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988111 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=jP68gOE9; 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 4X9ZtR476Nz1y2P for ; Sat, 21 Sep 2024 13:46:23 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D053288B49; Sat, 21 Sep 2024 05:44:28 +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="jP68gOE9"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id CA7F7889C5; Sat, 21 Sep 2024 05:44:24 +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-VI1-obe.outbound.protection.outlook.com (mail-vi1eur03on20723.outbound.protection.outlook.com [IPv6:2a01:111:f403:260c::723]) (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 8FC8588A58 for ; Sat, 21 Sep 2024 05:44:19 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=SoBNENfPlZXoyUmQuNDRfp/g6dxBV8HO01NWgqqy4R3T/Earxvh3CAomWPLkm3jVgRG/1IausA0mC+Yv+cGQgzChXvIh81o+kEaBKhIsoxf2TZaxczuDEppMa7TaBuF4cmwiDvz6ww2TRGtVXAllDUQyYp1c+L0L1GNBH3qfK8Bo+XS7Cx0h082IOovapHc4Y45nj79GwB0y0MWjzXkZ9MKJm59qD3T/dWzrK5MyEkOxVWmQ59aRyyAIt1LQNoifoZjeeJbCWco+wMCc/1iGrIOlFx1V/cPJqNk90xXJtYzFYns4VfIqH+0F9uhQtlvFreHOuJskEBtyfyhniaJvxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=kWxga44Exx31SK/nLCWA1BNlOy7Q4PLjJS17taa2qvk=; b=yPjBli7XEyDlHcigVKF+x+nexasmjpw/nBW1wNRSk98A0O8V3YoukK3RFzyEn/L0O8Bn8XO8xXRma6QcJuHi7WoY+eVkaltRfGAa7bkSxeKWg1EIV1ylRum7K16RgW+b5nn8UO71IAq5nUrmS6j9T9IJlvQ9oI651i9smcnn02eF14GotwD7rjo6rNAjZtgkVZqzOKhyrBo+888lKfvhegJTrjpQx5j4kK+XAhFo4FPnWKTqyttk1AuYYf4Dsp7i2oHUfTf2pceOiDjryFiB9SEueYkyt3bwt4c1JInAYb7A+55BJHfoUsFMsmO0CEHaJVRksYU6XLrO1AnV3m8L0Q== 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=kWxga44Exx31SK/nLCWA1BNlOy7Q4PLjJS17taa2qvk=; b=jP68gOE9VW2U3jlObQxeRwQzA0UpGiYDnDBPNOX0DrPgT8Vzienb/D1tfOmaDftJ2MuZQvSCFH/Y7mfwHms8S/MAU025BkVRpKDWODb2Rj4aPWIfF/E576gSTI/nk6RBFJw0bN3wES/pJHc5JmNTDVoMFUwRL0UtMpLFIVxuf8K8D3igBt27Vdk7uUsYDUNgPpTRbl2POwHNSX1x7sx94acZ4qMAh9YTyJ4U6sQNt/8gAq504Kp9CDlFSRNz2OHKTeZBf0vt9sY8tQYiY8vK5rMEzPzLlG5Ys+5O0mFpHNX6CNdCnicu1EYcfVlZiih9WrX/A9FqdZYuTa59GiEaew== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:17 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:17 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 11/13] net/netcat: add netcat over tcp support Date: Sat, 21 Sep 2024 06:43:51 +0300 Message-ID: <20240921034353.1298452-12-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: a97984f3-cd11-40f5-04af-08dcd9efab58 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: TFottE5B+XJqPJHUh3gscM1zVt+QA5xke0teQYNIXRurOPxABSrJXUpK+NupOwiy0srI9axJfsmVS3eS7COZfF9ajDfO7hekQRfXvrMNaA+e6/zWPJyhb8GKOostojYMLCMs2i/QwdG4kkd5CVcZ1zOSLV2YxAZhHXTVq9zlCoxaQOtq8RyqsjLTlHz/3S+Fug9T1ANKEDb7P3iUOflxME077nDaQbAb6NNvh/VcGOf9LiDIddNjz2ixGPoeX6zxZUoY85pYdtL+AMJDxDc8+fu+7w74QXd93qUZZt1xx3qiJN40tnmHb4SwaTKfMdDlEZdi+xaKsPjtryQ+rKdpzje9uYCobVvr0u0f9HIAlKSci+43kL8twZTlZX6XtjeEYlkAabECP+XjP9i2tQDDRXRhEU7M40ow+IBNs9E9w6QbV88nokWQ2IHNm1hnOTknh4EVrdaTZtIZSsVZUOo0LQYlo9zKLNdRHUIImbij+dyaiBshMMY19d25xM4R9EoxFTHrTcoBGVelsE9jO4FlhDAYYxvncnDjnHICsXOYU8Kjd7Q4aqvtxBQU62HL+ADzS0omeXRVdnaBfsGq88/FZJtT/OaLnORIZolW7Qvx7lnWq0uykr/wQP3YDO3qg8ZCPQYHok3AC1IU6LibIEh5aAJv9+4DFTpRO0LTpTibktjZEhaRQ3oMJUB64VeUdpyLsrLM1U/rv6i1rkM6QROWLrQ8kfkH80fX5gGlCnO5WzPh2e4W1TUagVVpK1bZGDZc267oTvQbVjOCxAnsP0smt0UhwsqazUrdoLGrnhYi8YAHsNf6a6+zComfTsrYxXUpLFbJjnLniASJRkWjxdApGCmM1ummla3gMsxtlDF5Zn285o7RUSsH8nhEq4nf1qFl5A1gmRZX8x7e4Kgv0RC09Pm02ho+0smTzfhd3mOBHOjBjAZVm5RSuRgLKLiSEaAW/QZMHhVizFt2kdG0HUT499dfGSp+6be3yUOwFfRhHQ1ICeAkkAsBd0pKFdPAgPcusMVSp0g5bF8FpPWuQ8Z2Yn0aMV5Ongn8HyV5xBMAgbEpRVVYQqwkLoKclnoN6uVHO1DPAKCU+SPM5suXY1S7Uwm7evG6rME8YdRHpgVosYskBCpr9VO/PO0Mg8svhW1J4JY2ZYLpb2UL9yszSJ9dBfTA1h01Xr6OaczkFy++f6mGumNiELEedl3TPFuqLMZAMCt0pXDJi6RnRgb2dOdbfy2WKvXBvtKdbhirenISV9T8wX4wCBbVZm/7SlOBucmMJFovOEzCIbZWjnhoQ4mpuLvhLQcukh0dGfohnn091nnqlbXD85gPOwPDr8wHcjR+cCLTKDWq9X33z/myHyFXMJG2m+s740fX/VhO6mvzSh0= 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: oAX3E/HDsJHY0gsd51nUAYSkEof+wBXN+/V5MNNFPrV6MBKY/nDQy6hQ6DxW4e/D2b3ZT62sy/yfkAYMumXSHRqB1Lfn9tfAU5dG5j7B4+ceLKGgZs6C5tkPMl9Tlc3OH0HR7VKuscnCYgsXRV3brR4mCoMsKRupy3qzTnFYaCZWr4UHAHHRCsHTiL5HJuJrPu/YzBMw2BoQi150M/I8UyS6FpaqF/qUHxbuqjn8QcIzoNz28QkSKJ/VyWDBUKy84oduP/AuXdR/VXGyLfuHdEfpD6dBNEQjOYEfLe36xChBn3ZseXDu/VL3Fvm0/FguyryNnM09oEvKMiptSt1yizCK72sxXW6Np0fjp1UfYAtLvq8NNLyLoAg7nkDgdZtSfSheyg4hIpzc+m6sA5bVGbgGXabm0UAtIZQIAORvPolAvTQM+6JaPLRGGejlC4YyfmAdu3m8b3BfXzVM8rGG2mmbFMHFAuEeqpY4TXLUr1p+obrDHC0y42xXTbEvsLTNNVVJC27+b5z+31kotQqHgfPTkzJdMPJ2t+abuYMNPsW8U8cJUZpYYLJe2YNhN1x5BJE1x74nrP+AwlkkmCw5TMVlsjIae8GVxzJ88fH/EYmhT1Qqe6jKEzdRD69Bt1gboLulMdQD/8bag2zBhGchWO+oxg1ffV4dWstv7V4sTYDOaBiFrIgVWR3T9zgq13L9tonRNjtBxRaFEUKsB50KLJrfcZm5OrtOOrourJRR1aJ40ZSyxyREyETIampSgG4Hu8Ve8UU7k08P6nmpywqETs/SPYo4F4bTxp58NBqkFhN95EErJyOWNewTjHU7oDTPdTKqed+3fZjWzdhPjHlMpg9GmjoTSC8TZoTnKLirgG48g4HuN7F7a4Xfajwt8JGpZukOFD7+KkNk7o8aYTojakr/g8XeAj5q+yMPXb9HcjpaEgeLnHWiDRWbgrD0d8EEx9Jwa3o4M4gWaJcjFXotrbGDcntXBguKEWu1NZQwHt3mAD4k+jdv9krMv2Inct8PFAcKO/nuR7+elN8xbGSlnCPjbEV8Hdnmn+wb1PGpWmcTNztSS/wXmSKfdQQXzI3OqHJcS0RNVIFUV+WDKyH5OZzjHTkwDMiDtrM3uEOkznfkVHTDm0Q10h1g4SV/QhnvRws6Dtrl4hSChkAZfE/4r/1rz1W7AwqsMI57sYGh9MgQ0OWogEJ79M6Gsn32JO5oUQeE1Rfb8Wgov1AudipDfRmXNhX31B5OQ3wPm9ld/7P1RCdlQ7Ly98xNLPkX7Ju/FeSbgi3fU72Cjco+VR1g0RmHghjn58gYdVDAHDkfwiZ36l9FfKsH4U6Xc8U8Za1nq07KkGVVqBtSkHD7Zy3kienGVNCcnXKWiwgYBB1HPCH1qtX38kdDeNX1q8rV+TW6shhU0XSoMDTvRjrWJfbufjB1W25DL79PMphbB9JZA1IW0L5KpAG6LCEjkjADpvIR4WEWYumq71nYKKHz7fCIPI6iy5b0zhI/sV+yDWBrSoQS6CT8xI0uw2CDoA7ULdh1OBxItl7R2tdbvlbZic2XIksQ/E6cNPxGUfSYNUrD85dz6M4M9yA5q9iIMnr1UM9D1Ri3Btr4KCjbGPij4z/emqmNkqjz3pWqXZG461G/fJ4= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: a97984f3-cd11-40f5-04af-08dcd9efab58 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:17.6245 (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: n841/lcgCdJy+eFH4uDBD4O9RNqzAb1SAKUv+JKjMmR8wSOSYh+KW5m6z9HLQ59OIuKuN7E/1BJiADl0IHUamI2plePqe7y2NEjXtsVaXl4= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 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. How to test: ============ netcat-openbsd=1.219-1 from debian were used for a tests a) Load data from remote host. * U-Boot listen on tcp port 3456 * PC connects u-boot: netcat load ${loadaddr} 3456 PC: netcat -q1 ${UBOOT_IP} 3456 < image.itb b) Load data from remote host. * PC listen on tcp port 3456 * U-Boot connects PC: netcat -q1 -l -p 3456 < image.itb u-boot: netcat load ${loadaddr} ${PC_IP}:3456 c) Save data to remote host * U-Boot listen on tcp port 3456 * PC connects u-boot: netcat save ${loadaddr} ${data_size_in_hex} 3456 PC: netcat -w1 ${UBOOT_IP} 3456 >image.itb d) Save data to remote host * PC listen on tcp port 3456 * U-Boot connects PC: netcat -w1 -l -p 3456 >image.itb u-boot: netcat save ${loadaddr} ${data_size_in_hex} ${PC_IP}:3456 Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- cmd/Kconfig | 10 +++ cmd/net.c | 35 ++++++-- include/net.h | 2 +- include/net/netcat.h | 20 +++++ net/Makefile | 1 + net/net.c | 9 ++ net/netcat.c | 194 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 265 insertions(+), 6 deletions(-) create mode 100644 include/net/netcat.h create mode 100644 net/netcat.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 978f44eda42..cfdc53e494a 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2007,6 +2007,16 @@ 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 well-known netcat (nc) utility. Unlike classic netcat utility + this command supports TCP-based data transfer only, thus no data + will be lost or reordered. Any netcat implementation should work, + but openbsd one was tested only. + config CMD_MII bool "mii" imply CMD_MDIO diff --git a/cmd/net.c b/cmd/net.c index 53ce2bc5d0c..79bb126dbd4 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -206,6 +206,29 @@ U_BOOT_CMD( ); #endif +#if defined(CONFIG_CMD_NETCAT) +static int do_netcat_load(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + return netboot_common(NETCAT_LOAD, cmdtp, argc, argv); +} + +static int do_netcat_save(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + return netboot_common(NETCAT_SAVE, cmdtp, argc, argv); +} + +U_BOOT_LONGHELP(netcat, + "load [loadAddress] [[hostIPaddr:]port]\n" + "save Address Size [[hostIPaddr:]port]"); + +U_BOOT_CMD_WITH_SUBCMDS(netcat, + "load/store data over plain TCP via netcat utility", netcat_help_text, + U_BOOT_SUBCMD_MKENT(load, 1, 0, do_netcat_load), + U_BOOT_SUBCMD_MKENT(save, 3, 0, do_netcat_save)); +#endif + static void netboot_update_env(void) { char tmp[46]; @@ -323,16 +346,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_SAVE)) 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_SAVE)) return 1; /* * Only one arg - accept two forms: @@ -354,7 +378,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_SAVE)) { if (parse_addr_size(argv)) return 1; } else { @@ -365,7 +390,7 @@ static int parse_args(enum proto_t proto, int argc, char *const argv[]) } break; -#ifdef CONFIG_CMD_TFTPPUT +#if defined(CONFIG_CMD_TFTPPUT) || defined(CONFIG_CMD_NETCAT) case 4: if (parse_addr_size(argv)) return 1; diff --git a/include/net.h b/include/net.h index b0ce13e0a9d..0af6493788a 100644 --- a/include/net.h +++ b/include/net.h @@ -515,7 +515,7 @@ extern int net_restart_wrap; /* Tried all network devices */ enum proto_t { BOOTP, RARP, ARP, TFTPGET, DHCP, DHCP6, PING, PING6, DNS, NFS, CDP, NETCONS, SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT_UDP, FASTBOOT_TCP, - WOL, UDP, NCSI, WGET, RS + WOL, UDP, NCSI, WGET, NETCAT_LOAD, NETCAT_SAVE, 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..d8e09aaaa55 --- /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_save_start() - begin netcat in data saving mode + */ +void netcat_save_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 92156b5058b..acc9a6edb36 100644 --- a/net/net.c +++ b/net/net.c @@ -102,6 +102,7 @@ #include #include #include +#include #if defined(CONFIG_CMD_PCAP) #include #endif @@ -566,6 +567,14 @@ restart: wget_start(); break; #endif +#if defined(CONFIG_CMD_NETCAT) + case NETCAT_LOAD: + netcat_load_start(); + break; + case NETCAT_SAVE: + netcat_save_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..f0c387e58e1 --- /dev/null +++ b/net/netcat.c @@ -0,0 +1,194 @@ +// 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 +#define MARKER_STEP 10 + +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 int marker, marks_in_line; +static enum net_loop_state netcat_loop_state; + +static void show_block_marker(void) +{ + for (; marker + MARKER_STEP <= packets; marker += MARKER_STEP) { + marks_in_line++; + putc('#'); + if (marks_in_line == HASHES_PER_LINE) { + marks_in_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; + + /* + * The status line will be shown after the download/upload + * progress (see show_block_marker() function). This progress + * generally have no final "\n", so jump to new line before + * output the status + */ + 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) + return 0; + + packets++; + ptr = map_sysmem(image_save_addr + tx_offs, maxlen); + memcpy(buf, ptr, maxlen); + unmap_sysmem(ptr); + + return maxlen; +} + +/* + * This function will be called on new connections (incoming or outgoing) + * It MUST: + * -- setup required tcp_stream callbacks (if connection will be accepted) + * -- return a connection verdict: + * 0: discard connection + * 1: accept connection + */ +static int tcp_stream_on_create(struct tcp_stream *tcp) +{ + if (listen) { + /* + * We are listening for incoming connections. + * Accept connections to netcat listen port only. + */ + if (tcp->lport != local_port) + return 0; + } else { + /* + * We are connecting to remote host. + * Check remote IP:port to make sure that this is our connection + */ + 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; + marker = 0; + marks_in_line = 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, ':')) { + 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) { + 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_save_start(void) +{ + reading = 0; + + return netcat_start(); +} From patchwork Sat Sep 21 03:43:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988112 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=eR3q78tg; 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 4X9Ztg41w9z1y2P for ; Sat, 21 Sep 2024 13:46:35 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 3F8AA88B8F; Sat, 21 Sep 2024 05:44:29 +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="eR3q78tg"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 88232889ED; Sat, 21 Sep 2024 05:44:25 +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_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03on20712.outbound.protection.outlook.com [IPv6:2a01:111:f403:260d::712]) (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 EEBCF88413 for ; Sat, 21 Sep 2024 05:44:20 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=GJ+NhAveP/yLx4Et4SYNC9EmDV9ZLYRC65UWO0sDHrZdnYdofOaBcErRIIwRNvnapBUxRjYbIpPtP9vpSsdbgd1DlxADDuY6XTfVcxaNn02PZ57GMQ88Y9cEmU+vgmuYK63GYuFqeWqOWkzOUpTtfbW9OE/Fb4t0+hdAx5i/D65pTD/Dl+qCahYyPIU1Wf3NI76Uj6M5F5M2jBC3royXlEGs9o3yiLwWh6enLbAHST35Xet/192xPZAZVaFG/AXgKwA7b+OhsMbaTOVN6BjiFGP3xRsYrDv4ceXpWTAtRfn2Th/SeubxCO+k4HXbploFylB+TXNB4G5l1SQzl0GGwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=OaqbrP6mwHd2XHP5LnmRxqPbLwLiWz5yWpzzrlqaM3k=; b=YWN1eZH3cGgo/JzDQ38FjPFWJAeUgoE4zKKej+AEb0cHuU+JpUWPYDyzMiFU1/WPPu0z3sDmmZNukVZEmKZBKsZpTms95mjidH83LgIsILrvsRt9II1sVZVGy8q8nVDur3CxS4lVxwk8+YiFYAP/zt1Bu8thU48ipEUrddgKcwMo73VqJzMDsoOVa5fZoxOm8IlNHOqByKOTyvlJqJoGbNJTdcWJtLKxVfSuolPODGWCu4G4SS12AbCo0l1NHLEUyHyH1332XYNJQVJYGACMuTEac0DC3XjqXjCPqfmCUUniz1MxQSVWZ2ch8cC7YLW7IzO2jVs59hLR5Iolvwk5lw== 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=OaqbrP6mwHd2XHP5LnmRxqPbLwLiWz5yWpzzrlqaM3k=; b=eR3q78tgnPimoSQeHKp37Jhrf17ec6ASOzMZOoZhTx5feraNmkk+fe0OzY4ClWc/X6+qdY/lNPPOGDZ+QoTn+Y0IFT69kRD0ZSbFW+OVRkP1bFql3hXT11DUZL4K9BTCLd6p/1n/JyqLnNxqFgNrRpiUvHKfZnibMgjMN9PZOvPDg1g6RzlSV81zZtrok+RH6Ayu40Ug6caQjfCaBQy/iCdt7uzOBtAuTRg0xbTtCPTraMBjAFFrcQ8YKfoyDd7ZdWI6oFKcK5jCvMzVqC+SN4yseqz9upnfPVyRNmbLDMIKhYQiOyqzIceBVM/mWWR4mU4EtFg8p6vwt98Ndf09TQ== 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 DU0PR08MB9418.eurprd08.prod.outlook.com (2603:10a6:10:421::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8005.7; Sat, 21 Sep 2024 03:44:19 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:19 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 12/13] net/httpd: add httpd common code Date: Sat, 21 Sep 2024 06:43:52 +0300 Message-ID: <20240921034353.1298452-13-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DU0PR08MB9418:EE_ X-MS-Office365-Filtering-Correlation-Id: 5ecc631c-395d-4d25-4f98-08dcd9efac2f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|7416014|52116014|376014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: vc/q/TeNUPsu1shxbHFxu44eCecSPSPDv0o5hMytHvFR/6EllAyHFwvWKttPFUBUfGFD+gZUWAZTCSZWrKWM7uEuSyJ2jCatmG2VIi+wMKOUhXdnezLC8bnznrSTTQD05RiQg+XJdeppf4DADltNCcCsli7mJPXxTVU21PpUePC2fZCcoN17nv1xmfdCIzxVejdcHT3oZ5hlEdULJd6zy1JTJItSNhNmD/MaYX0IfJ+mQDCycldenZUTw7JN8oyyTFNq6uPTW5CzESDeMMOU04xNAr+xAAAmkvkNeEsxCaU7X4DPTgjH/aKJh+6L9/Hl0DzjI8HFm43+a8KEIjwiU8HccqOODUroYdmGG1u6HI3tGNmGNNrMidhLjrrxgvNz8Fvd8xS1xMTTS12Z5FIePHyMWSXw7D7FdmkShYeoqmdBnzfZ7XY3nPCLdrekOUpox1iAcGIuJ8Qu+WhnHADjy3Fw72R80GD85K5oRN9Ru1DzS83g7Q8M3KzZQ23UbhrDsVWheqBO/WcFM/69hbyUQK5co0Aaj7AltgX7MDM1grXfJB4FrAFbyXJTq2RE2C5W0U5e0ERgju/ESKcD2pzkHMklY3T5P/zjaVjNYdtOh7fsXusGFI8UXgE/NnVrNr4pqYqbc4I43UtQ8hmmSiuNF/ghSQaDLenSr2N5thkgut9NQtOZK6dMmevhW2PJvtSMDx3qD6+ZN2jF0dhuGusAzgiCUf2DWrtOHzSIna4WBVCjyNzOG8D37UlWXx5x6kQQ0AeOD5XofbvHIJCaB2CqmL7Z6TiPEFcAD1gmZ+coc3Yf46hEqFqYuCh8n8mb2jBNhtEAjxNy3NJxbbdnrQd7+aOfVxNDrk4K/55F20rHvKZSOTt/yr9+xQzfWzW2wp8thAUtJo3y4+mgMWb5UZuD9fbgwaSIgdreIVvvK1c5BagAJT6IUMQCyAJB60RhY4LjTa7ygTbVCgIb4ikE0kUmgj6Kt8GaC6igMZDwWCrcZ9FfeW5PeFag4VPUJIWEiXSA+meFPWZ3rsl+OhlVGNW/1QVbSc4S5jkWr5ixT1JW54JRfKi+R6HqN2AC1/Xr+yMFr9nLUfXVv8v3tA31k9qlk8qUgPvpoE4qeKif8hyiQqchSwYHLQZmhBd0sH7eTCqytOmc0CQSPumgxObetfvhc02Qnf6XrUX2kKfuOmoZhHDxMVoimh+bVgJniCHUv5nCmLpuOizQVtzIR08CqLk7EC77AHDws1MkF6HOx55dkh/iLW4R0EInf9xK1sbJb411kUaRA9ZdeXLxieD/gLzUT9Q1MruGzSJMTCn4yA7fisD57n7LS7Pe1iAF/Qq/yz52zmp/rTWkeRaZR1Q/fpCrXaa9noZaOmgCvCkDem/B440= 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)(7416014)(52116014)(376014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: dk9qUY8B8wSCmYncC6XpiqkweSs0XnqKK942VLwuW8pTTl2gtp5x3arF6lbCuylo7V3RW+mo5SGvJCE5e+yDnr2Kb2iWy6WtBh9NacpIwMf+usEhXqamGJ1k4oODR0Pn/bS0LzdDDQZ3D9UVuTYsPiSiO4Gum89QWkveELK/kxXVoiQ01N9LSLlap3+jF43id5q7lCieFpAjirFcBAkYM5UuEoXqXggIi33yvGvjy4gOmnpo2HktEjpqz9B3rDmLxH+0BUFogExjysaxHs+pISZaXCkwrqZUc+Rv6LhF8gYgNTgQ/5cybNuW0SzfXq/NR79tl9HdklN8+CdvHdUZFr+qjdxv6XkNLYI/HcAtAUGEDb9fetWngHUou9jEQL2Gl8cVrIR9Kx9WMkLRoBvjqn6qAkBSSenYtxf36ugTPa1kKwF6EsHRoF/wS+u//GKhFHMbfcizfk9g9sDOlFOm8rZGKZ6Of67jvcm2Nnx3G6r78Og4WA2klIDJGYol4iTs38SvsV11PV2fgukaghf258Z0+KEswJi/rFCpFS/NY2xpE/N4ebeeHrlRDgywMDumHsGCyT8ebq1Cc/p4Bwp13V/ekxQ4sRVfLecCxsBfUaHKbB00GM6+lfX1MR48G3omr2o41/uICDQfV+cQ4xpepl241rySoLEahwajMLis/UR4xI0SIB1c68AbYB5EBxsRqY5awimz+wSzinA267BXTPBnjJgNtiFMtG6UO47jGOnwdjXSfg7fYiSLhg6Y7WJthKQOCJ2/hEJQlP/OCDMCtNxQF+RKEmLH26ha3F+35XTNbeMi09H87t641bel7OJVdGaypySepBQ0aooXneeYVF5ibRi1YxIR1Kt4TPU335kon448tOThjWxLoHFoNv5CQcbUadAXKIzITkOvagaiz6KlHZB5MFzcJLIRUaUUx4Cmgs2ym54QAsJgI+gDk7ITPLJ88rhUVWiP7z/V4L2RN3aTVluGmyBPPA+/oz0HCsNeq4tNzXN1VTMWYagEvIlytNa9cijqd6MYOVmWjLnzGD7Tn+30NJbGXZqn7dMCMfk+O2aBq5oTzEQbhY2KLxl5OsyVGcggJdw/S8qBskMZbbqr45pHPoKiwe3HgmdcJ4In0KiE9WUJEZQIqWaKVu2OJFPu1qVOO0B3tySD4kxcnF+4j6mgXTQAtPvPS2wGAf9UJ0NJktUb7iDtwaH0XPfaMAMyOIos03yxRw+YPulKycqKOyeT0us4FLvulqSOo4T086H+gVNjLBRZDeqCiIVaAjiZUYhTDXZUuKE75hzeQ4TATmh79ACejIEGVLK+XWr8qoT9QN0ivrMmG1JMV0tVojHY/rOXV8fNVoTtxzLAKGz7q2TTeTIl9ZhCTOy7MBLGv/oUMNiMgI2tEqrfuucwp0uHaCuCbVGjLMKr07GhSKjoJ4XRdhBNW5afQUNFHmcySBEM6GKqxgwo0yNivj9gHXV/6iUogxM+rnfh7mbRnda0Vl2Z2rNhjmW357QilkrytSOYmHxSpyD1uJ6C8LJbKcS8V32ov5CosvQ2viORu+eIDKuC5EfaFncnrhFIyU3jnSd8CI9necBf4Goff879X6l9QjKjO24+tJSidhyBDDY5U6EuVS2BUiGaSxnYejI= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 5ecc631c-395d-4d25-4f98-08dcd9efac2f X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:19.0432 (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: eilt62yH+QVWMGBgJLkfy+mUHFKTT75Hkmx+r4z5qjXISMcDmbSFH/txTZgSimnLnTNPo4ZcYPx5B55OyKL3QZkQzaTJD4ovCtrtcK/Qh3g= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9418 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 Reviewed-by: Simon Glass --- include/net.h | 2 +- include/net/httpd.h | 64 ++++ net/Kconfig | 14 + net/Makefile | 1 + net/httpd.c | 730 ++++++++++++++++++++++++++++++++++++++++++++ net/net.c | 6 + 6 files changed, 816 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 0af6493788a..154885a2b7e 100644 --- a/include/net.h +++ b/include/net.h @@ -515,7 +515,7 @@ extern int net_restart_wrap; /* Tried all network devices */ enum proto_t { BOOTP, RARP, ARP, TFTPGET, DHCP, DHCP6, PING, PING6, DNS, NFS, CDP, NETCONS, SNTP, TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT_UDP, FASTBOOT_TCP, - WOL, UDP, NCSI, WGET, NETCAT_LOAD, NETCAT_SAVE, RS + WOL, UDP, NCSI, WGET, NETCAT_LOAD, NETCAT_SAVE, 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 7cb80b880a9..55739b9bc98 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..743c2b712b8 --- /dev/null +++ b/net/httpd.c @@ -0,0 +1,730 @@ +// 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_method { + HTTP_UNKNOWN = -1, + HTTP_GET, + HTTP_POST, + HTTP_HEAD, + HTTP_OPTIONS, +}; + +/** + * struct httpd_priv - private data of HTTP request processing + * @req_state: state of the HTTP request processing + * @tcp: TCP connection of this HTTP request + * + * Data collected from the HTTP request and request header + * --------------------------------------------------------------------------- + * @method: HTTP request method + * @url: HTTP request URL + * @version_major: Major version number of HTTP protocol + * @version_minor: Minor version number of HTTP protocol + * @hdr_len: Length of the HTTP request header + * + * Data for the multipart/form-data POST requests + * --------------------------------------------------------------------------- + * @post_fstart: File data beginning offset (from start of tcp rx stream) + * @post_flen: Length of the passed file + * @post_fname: Name of the passed file (see 'filename' tag of the + * 'Content-Disposition:' line of multipart/form-data + * body) + * @post_name: (see 'name' tag of the 'Content-Disposition:' line + * of multipart/form-data body) + * @post_boundary: The boundary of multipart/form-data body + * + * Data returned by the HTTP get/post callbacks or error handler + * --------------------------------------------------------------------------- + * @reply_code: HTTP reply code + * @reply_fstart: End of the HTTP reply header and start of the reply + * file data (offset from start of tcp tx stream). + * @reply_flen: Length of reply file. Zero if no file needs to be sent + * in reply. + * @reply_fdata: Pointer to reply file data. NULL if no file needs to + * sent in reply. + * + * @rx_processed: Currect reading position in TCP stream + * @buf: Buffer for HTTP request/reply headers. Incoming file + * data will be stored in the memory starting from + * ${loadaddr} address. + */ +struct httpd_priv { + enum http_req_state req_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) + cfg->on_req_end(tcp->priv); + + free(tcp->priv); + + if (stop_server) + net_set_state(cfg->on_stop ? 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)) { + priv->method = HTTP_GET; + url = line + 4; + } else if (!strncasecmp(line, "POST ", 5)) { + priv->method = HTTP_POST; + url = line + 5; + } else if (!strncasecmp(line, "HEAD ", 5)) { + priv->method = HTTP_HEAD; + url = line + 5; + } else if (!strncasecmp(line, "OPTIONS ", 8)) { + priv->method = HTTP_OPTIONS; + url = line + 8; + } else { + /* unknown request */ + return HTTPD_CLNT_RST; + } + + version = strstr(url, " "); + if (!version) { + /* 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) { + 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)) { + /* 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) { + 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)) { + 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)) { + data = strstr(line + len, " boundary="); + if (!data) { + /* 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)) { + /* 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 (!priv->post_flen) { + /* do not allow zero sized uploads */ + return HTTPD_BAD_REQ; + } + + if (cfg->pre_post) { + 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)) { + data = strstr(line + len, " name=\""); + if (!data) { + /* name attribute not found */ + return HTTPD_BAD_REQ; + } + + data += strlen(" name=\""); + end = strstr(data, "\""); + if (!end) { + /* 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) { + /* filename attribute not found */ + return HTTPD_BAD_REQ; + } + + data += strlen(" filename=\""); + end = strstr(data, "\""); + if (!end) { + /* 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) || + 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) + 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) { + ret = HTTPD_BAD_REQ; + goto error; + } + reply = cfg->get(priv, priv->url); + break; + + case HTTP_POST: + if (!cfg->post) { + 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 || stop_server || tcp->lport != HTTP_PORT) + return 0; + + priv = malloc(sizeof(struct httpd_priv)); + if (!priv) + 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) { + 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 acc9a6edb36..5f2f7a2ec7c 100644 --- a/net/net.c +++ b/net/net.c @@ -101,6 +101,7 @@ #include #include #include +#include #include #include #if defined(CONFIG_CMD_PCAP) @@ -575,6 +576,11 @@ restart: netcat_save_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 Sat Sep 21 03:43:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1988113 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=PUuWNuCC; 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 4X9Zts60Sxz1y2P for ; Sat, 21 Sep 2024 13:46:45 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B16E188BBC; Sat, 21 Sep 2024 05:44:29 +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="PUuWNuCC"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C5577887D1; Sat, 21 Sep 2024 05:44:26 +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-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on20701.outbound.protection.outlook.com [IPv6:2a01:111:f403:2614::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 43AB388641 for ; Sat, 21 Sep 2024 05:44:23 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FGcXgHHoPF1sOYFAEHJTtt7N5BCT75UFh5O4w7A/Kdpo7dYDCUZe0S0hMPmlSlCHlxzxWPFsY86ABnhk+REyyxow/84uMNwdCbpKEkc85qUrwjteUX2LKB2kJkdTtYSAz6mQUUDAF/FDoQ8ubdFivqCiNNQZaZzSfa3Y9Cn//cszpA1MH5VnqO8JSo8GB3qvJP/yOuvg1QfQwemyfE89iYlwSvuzD3rdbANInoIVPWPhuMYdWOvQdNBa0/S/GNAhVj+WpFcy+tr7vwnakJFyoxBKyGe6gpb9eG4WXaYm4U8nVb04DsPatZxdjkQJG4O5jxC+vwZOacYhqfNHGf6Yhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=yAai+B3NX7mh8fnORRGFZEmiBJfbH9GLQrs9gP+sQhs=; b=gO6o8XgiEKoLdQmE1FC8GgEjhkkLtUfrfLMsO4cZffmOf9v8+WzNEtzm7FbKrL1og9/Z32KEpA5jLnsAXAAoRMxFNUc+lk2gjElsen+CBgGmhnkZJWNKywP6RUqVCOeT7OqgtBF1u/sSzkgnHEjACeeqjcVfuWPr8VgTvZcFZTCd0F2wYkCikqH/+k6gpfhGJUDh+wU0/NrFyqjPMbhsIgLjnjdpVS0Fsh/xQ2O/Z8mg4Nvzq0P0QdckgHsgSZQmsle+H2HXky+Rwpmjb8WOWz5oU4by7/fEsw45gtqiKAOaawfikEk8dwG6M0e9M6N54HUVavZKKvjc8qEjv3u31w== 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=yAai+B3NX7mh8fnORRGFZEmiBJfbH9GLQrs9gP+sQhs=; b=PUuWNuCCMJ+zRdP3upuO3G0YygeFuqVeMScNE7GlHqb3Gg7ASzSsRdQGITFfnvq/xaoeTuHZtdeHMSb6r53CsA/QO+ZNdLjo6dm/qIJalrktPxGW2gaOig1YHz/bLweNSJ/+p15pNmq5opMgwWC5GQvYVoUSJPBIWv0uNhTMRQ1+ZPy1CN4c1NCJX/DWqZogpsUaKzSCNhDn5H+DMTkKaU3gvTZthfQKKZ+KefMZ79loUxE6L/wHqH5Tx+52HussjYsrJhM5efASs6savyUlkG5dsoyC7dwEf1JDcYQoNpjVSlq5k7AxUS1i3+xA+yGnC+Z7ctnDWUCqNyEVM3VnCw== 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 PAWPR08MB8933.eurprd08.prod.outlook.com (2603:10a6:102:33d::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7982.16; Sat, 21 Sep 2024 03:44:20 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.8005.010; Sat, 21 Sep 2024 03:44:20 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Mikhail Kshevetskiy , AKASHI Takahiro , Heinrich Schuchardt , Michal Simek , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , u-boot@lists.denx.de Subject: [PATCH v7 13/13] net/httpd-upload: an example web-server implementation for file uploading Date: Sat, 21 Sep 2024 06:43:53 +0300 Message-ID: <20240921034353.1298452-14-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> References: <20240921034353.1298452-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: GV2PEPF00004595.SWEP280.PROD.OUTLOOK.COM (2603:10a6:158:401::440) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|PAWPR08MB8933:EE_ X-MS-Office365-Filtering-Correlation-Id: 6905d065-c41a-4329-3d69-08dcd9efad07 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|1800799024|7416014|366016|52116014|38350700014|921020; X-Microsoft-Antispam-Message-Info: SNWEKUJ8/h/jDKO5oD2Yi9xjM8KuPELLn/p1CxCVdBSq24qmOa/mphcAvCm85WjHIP5faJqQLtIb7qLo6Z2Lld9D2KfN7zIu0mpdD4GFO3qZSssuzSYv9gacCB2EAzJRjb1lhI7SRLubIBxCxFcl6yYPl28/luvl47eDTQruRMeH/7DBcRCNBb+Qx4NNVsZLos1rvb8mHv7Qch0adv8Z3/Rt7LoQz/WIxUAveLoKx4rG1ApH2s3pcg/6aWteRPzcy76xi7lOaAZQTD/1CMzy0SK7Y63rM1CkuV5w5D2h8y6/0Aqfo18rx7FLYUsaSp6lgrIcEBva0QfYtZ0ZHqtm5GPFIQwaUK1yjtQKCrhSzWvDZsj0FMMCooabcq5/x7r6ALnIxQx3A0Y7wzaYhtWkQdJV8RA8Z/3mGxuJDN11cSfHAqNzlvnl8YqpPbkrp16TTzx5ayjMce9Tl/yRqzrXASklw+8CuLLiMB02tv7uTmhTn8vYXi2QlwFAz/sLp5ng+qGElzoBE/8aPgzW1S9tM7Qpf8OGdGpZHYGJ7axtpH7tWnAUZxqlAYjNDFvWy61tq2zwJuhhfYceEZ9XersFLsrxLrbzq8Ydf9h2sBC9cutQKWCmkmlGWhL7kafJxWVhiXOQrSXt8Lc8KiHDAJlWdXJ0sBUsYDPw4MM/K0e+BTStXyM+/Y2M+LX0byWM8bQ7Isj1nkULwCg2oMmJr4e25/Eu86tRb+8d86YPKnPT2Z4nxhQCRUV2pnEI0EqiUF5ZoH2r3v/VNrvgzkVykv2QSaz3LtLoJr9RkT2Xikzzc6nEjyUCdnYglOapdxm9NlGVKUPE5cD0RQpj3ebR2vRfRdz8mdQNxhnixoDYdiGSZmyCfv0CPhQLKWS71b86ugcN+B5w4YqJvjmK0l/kfcMABjM4tL0gxtbNcTsWw3tJ2o2lOUiQhYgkVJnt4QfMQ6ZAg0XORkMFeKhKVNvNDwAM/KdWeEtejZjvPnXrPUmKtU4VCVvr58EVbKBsV1F0k72d/PYoDX8m+QJxJ6iPRmgiBtTYrvJQOBVHiF9emEIoISNX3wKiqlw2zkihk8w81b3ew1bp7y0L5am8+SOBlY/c9+LjiL8YqsYOMo9jdu+01zXLeNs4t8Q3zrZJHa73wbmqUO/4iMGg+kaX56S8IBx3189viRMgdk+8ePAiCwpwq1OgvY8+ekk+FKjnoOzdeNRDXy8XU7JsZA2NwIhZgL11nI/9zB0HsfesNMfzm21wZMdG8DdPW1b7At34moXPvFtX20eemBW4d9y5+CFSOYgDH3TPC98FNrXxLC1rUlqLZuXm47ypjgiuN/speceJsaGyRs2PG5efVY4HVsn8nad/B9dMEBTSNFNL1G6R1BmOEuTIffz7QxztBI5Zc/ndS+PzUh2A4oIk/9RqxEA+q3w47ikASx1w9Q9vOI/RYhsWjHg= 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)(1800799024)(7416014)(366016)(52116014)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: 2Tze4gOJwxe05zV87u+eaLxAcKrQrkSmx63RN82QZ1hmRTSpdIv4fevdMXmZ3ZaYHbNlx14H1TZTe2VQGIDbu2nrKbso4GUdzXxI3t7qaoQTLgwvXNy66k1N5DaeZngrDhih4/7lviB5Bz6UCyaPpy+DUpuV1miEUFlv4AxDd36DDm4pVLCNTe9QzgNwHmQ3ttaBqV4oSMBGs7N5vSop59pIL0CbJ/xESL9TsSKv3k80sFKcjdQswxwJ+RHKuRmqV0UilP8JIR2ncYA9zdE55/hvCx6o7jiBe5ulmgtAxdiVh3WGySpEba2HsGoT1ymy2Q9chpfu7Z5SYl709UlIHYG50OWkYn9Bz2MRtXpMfJKWYpkBisjzX/YqC5D5AH+6vvpMfVVxWZHnzIHKuiwPbSEcgsBJg8QL5gyP0kX1AZdPg0p5ex+1TSqMWrKu0w7DPW3IJm1x8zQKlxqTZovnx8V50D/0rgac93wMToR1WeSs0E9QbmaMA5+Jb1GdPsnMJV+Oh/vQIIEASG9xKQyFT49hiLQ4Q9PriFNMrFxt5Edk/sN/iwYjUgg7NlgxSjt47ZjYGTuHwuMoyiY4WBDUxVXzs8IQZX0eh1oJRdSHWlbVi74d+Hv3PDR6WqQfJjtWNFcop2mcwGeupfce5kRF2C5VIhJl25BatoBkPIjGGFX4XyigyFh79lujXSGv56YLTOX7oD4+SinQhn4zZHrLAAF7O4wcXNoczIJUWxaBzW14i65+nXKIEWpSEUM98+w93PRLs8XPmsymzEEHA8MeNp/WvsQW5f8kkZxZsa2QVXmWORL8y3tH/lAcs+Srq/OTUsxwdThVFh1QCBGS3ayFfBbnnWLMUYjPCgbAflMcw5BuD0b3+O2VXXiIvj1fWrJXRmhN++1T7NFPTISfF3rzo4mcCZFo/4xN34yVwMqrgLgB6iDXyPEygskaAJ9J3i500XRLHQVew6Xox9orPnSnNFlJ5y9vnIx74CC0F0ne4oefnrJ+rnsF4ROBq5C0yvVOui64I8RB8AF5pPQgQ43RVw2EJXlRcK+IdSCmi0neCNSE5kejwDryGwZl5J7iIXuIlswBFyrWc8SFM4JidpBmIRa/AiWpt890n0ggYtJUznA9NCFUrvb7vZskN/J9/A862ElvhjIMJY/LFB/aw+I1EVXdcjoibKhIqexavLx3rzkaHGWnJe5RGEsAZTKHlfUnubDB9rjZ5SPA2GO2kUmpx+ew0/FQHA6tlJgF3kEKhNIffyD3aPNAVsFCYVatDrcMEb0AQp8+YxjI+UwlsODuN4QGDLymJSuvDMb3XxR2jx984GY3U8nD7M4+2yD2TcfI7vsiU3nsARoSlXhWkgKM0PSGM/hihTIMoBXLr6UesyDgGgpl2N3/0RcKFm2RHVPw1WRwpedadLQIuINvOLL2SQoZpSWzW+TtfLzUFAsU6WMk7G4qRt6E3xy6oE2xvLFxjc+/wFrAucUN6LtCCs0MYkHkbwglgMU/qOVO+LFPZRQfT3D9TF+v2yBckI7bLyViB3bG8HckqUGAjam8VAHfoSLJYK/ZCDG+4mnKM3BhBfDWEUZ//0A+wAzBYQ+QwgrQLrgfwpn+2R4OC/X48MsFiBddk/S0PNDQHzJJDvX6PNQ= X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: 6905d065-c41a-4329-3d69-08dcd9efad07 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Sep 2024 03:44:20.4515 (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: FINV69XGKGUJYfyrtPz/EUqbcWMknVmJtcoDOawFDpey4ivGWlU0LIrEJEHp9u+A8+BAYWwPyGJ/att5JoR1fClJD1B7+hftIdPF1TaD/Pc= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAWPR08MB8933 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 is an example web-server implementation. It can be used for files uploading to u-boot using a web-browser. It acts much like tftpget, but no special servers needs to be installed by the user. This code can be used as a base for other implementations like firmware upgrade web-server used by some vendors. Usage: u-boot: start the we-server using the "httpd_upload" command PC: open the "http://your_uboot_ip" link in the browser Signed-off-by: Mikhail Kshevetskiy Reviewed-by: Simon Glass --- cmd/Kconfig | 25 ++++++ cmd/net.c | 20 +++++ include/net/httpd-upload.h | 12 +++ net/Makefile | 1 + net/httpd-upload.c | 170 +++++++++++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+) create mode 100644 include/net/httpd-upload.h create mode 100644 net/httpd-upload.c diff --git a/cmd/Kconfig b/cmd/Kconfig index cfdc53e494a..b7749525ae3 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2017,6 +2017,31 @@ config CMD_NETCAT will be lost or reordered. Any netcat implementation should work, but openbsd one was tested only. +config CMD_HTTPD_UPLOAD + bool "an example HTTP server for file uploading" + depends on HTTPD_COMMON + help + An example HTTP/1.1 compatible web-server implementation for file + uploading. It acts much like tftpboot command: put user data to a + specified memory location, but no special tools needs to be installed + on the user side. The only required tool is browser. + + Start 'httpd_upload' command, open a browser, connect to the board IP, + select file to upload and press 'Upload' button. This is enougth. + + There is no big profit from this code, but it can be used as a + reference for other web-server implementations (ex: web-based + firmware upgrade/recovery used by some router vendors) + +config CMD_HTTPD_UPLOAD_MAX_SIZE + int "Maximum uploading size" + depends on CMD_HTTPD_UPLOAD + default 209715200 + help + This option sets the resriction on the size of any uploaded file. + Please reserve 2--4 Kb more space due to additional space required + for storing of multipart/form-data header and footer. + config CMD_MII bool "mii" imply CMD_MDIO diff --git a/cmd/net.c b/cmd/net.c index 79bb126dbd4..f2df1eed2ef 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -21,6 +21,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 []); @@ -229,6 +232,23 @@ U_BOOT_CMD_WITH_SUBCMDS(netcat, U_BOOT_SUBCMD_MKENT(save, 3, 0, do_netcat_save)); #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..c1b41240aab 100644 --- a/net/Makefile +++ b/net/Makefile @@ -35,6 +35,7 @@ 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) diff --git a/net/httpd-upload.c b/net/httpd-upload.c new file mode 100644 index 00000000000..8e43860fa74 --- /dev/null +++ b/net/httpd-upload.c @@ -0,0 +1,170 @@ +// 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); + +static unsigned char error_400_html[] = + "\n" + " Bad request\n" + " \n" + "

400 - Bad Request

\n" + "

The request you are trying to do is wrong!

\n" + " \n" + "\n"; + +static unsigned char error_404_html[] = + "\n" + " Page not found\n" + " \n" + "

404 - Page not found

\n" + "

The page you were looking for doesn't exist!

\n" + " \n" + "\n"; + +static unsigned char index_html[] = + "\n" + " Upload File\n" + " \n" + "

Upload File.

\n" + "

\n" + " This will write the uploaded file to the memory area pointed\n" + " by ${loadaddr}.\n" + "

\n" + " File to upload:\n" + " \n" + "

\n" + "   \n" + "

\n" + "

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

\n" + "
\n" + "

\n" + " \n" + "\n"; + +static unsigned char upload_ok_html[] = + "\n" + " OK\n" + " \n" + "

Upload OK

\n" + "

The file was uploaded.

\n" + " \n" + "\n"; + +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")) + 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, "/")) + return &index; + if (!strcmp(url, "/index.html")) + 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; +}