From patchwork Mon Sep 9 22:27:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikhail Kshevetskiy X-Patchwork-Id: 1982839 X-Patchwork-Delegate: rfried.dev@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=iopsys.eu header.i=@iopsys.eu header.a=rsa-sha256 header.s=selector2 header.b=Utt8FAYI; 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 4X2hLJ0FZCz1y1C for ; Tue, 10 Sep 2024 08:28:08 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0180888E96; Tue, 10 Sep 2024 00:27:42 +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="Utt8FAYI"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C2C8988E88; Tue, 10 Sep 2024 00:27:40 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS, SPF_PASS 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 6F1AA88E5D for ; Tue, 10 Sep 2024 00:27:38 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=iopsys.eu Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=mikhail.kshevetskiy@genexis.eu ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=YM/ykJA61PDj4lOorxXXLd/1SAqkLudwYOD4RI36QK2iuTkoS3cchoHppIOXZhfSYLVhGb3gJ13LWzcSH2yFtCWJdEYJ2HeViCBlsFVrP3dSBEQpXVyoRTvL1xMdF/UfpNtBW8WjHYvPpOG85lpOBv9FtcNFPJrEPIOQ7/19tYO20s/nmST1T2ki+tFio/zEMOyH/x5md6FPbpuoVWoLuMcmXONra0ezDmJF/CdJy9TY1tvtXqeUPtTUbDJbk4joYhHysvRrOoafGATOAPGS/4mEth1PbdcWKLE1xJ5SWPUb/sl5hCxscGKmjvGyvSqGfBC6AP1ChxT0ZUOGMlrKhg== 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=Iz5OaA7SliKnnpUeZcWlRDIOZfPOWAJwTrnJLV7yCTr5M/PwztP7BjrdpwpyMR32ejFqbj6Iwp5a1huxf3DYFLg83uPEE69BeU6z8FqV7FMUGHCkccPelH0yUYKm1ddGZ2EzdSoWH8A/xQisO+iiemud+sbkjizG1vjf3xCsWP1whgQe0AktCAgWHt9RWXAh6bo6Gqo4Fv1d8tS5PkT/hfcE3b8opfuczCzKG1LvTalPyRsIb6DAUi3PhAWxvlvblgPNALBqJG5T5tPxo41qN/OSH8YEiK+hwmavGnWFehYbjKDTVZBJic+xuq4G7zNPts9+PUT1bspQpUU6bEEE0A== 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=Utt8FAYINe+F5JGzeCZeiGqfuzu5wQlaF9qyDyN6hekuw+3LkMBhe2jOmTwDhEO3DI8Rnmyw//Q2dYq63D2wgdhcbBEwvK4UQmqTJML9RhLb4JGjRZ1yriQgGD6+4rVnp/IPwVZ6t75rIn/GEc+by03dpcOszjYTEnoJ6YsYycvURle0pt0yFhOGJyev44UP1vpgInhERUEuasZnNE4zxBQ6pMj35EHblnhhh8MiVwp/GujmLz89/nK8pfwzJde68PKk5DvyFCAuX3iw9CTAJiWFMT/9pvjXa0NSOrRjPBNeH0ePONPtbiDHzmFpc5Qn73jsW4h6V/MUOm393YACdg== 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 DB9PR08MB8722.eurprd08.prod.outlook.com (2603:10a6:10:3d2::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7962.15; Mon, 9 Sep 2024 22:27:33 +0000 Received: from GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0]) by GV2PR08MB8121.eurprd08.prod.outlook.com ([fe80::4cd3:da80:2532:daa0%2]) with mapi id 15.20.7962.014; Mon, 9 Sep 2024 22:27:33 +0000 From: Mikhail Kshevetskiy To: Simon Glass , Tom Rini , Joe Hershberger , Ramon Fried , Mattijs Korpershoek , Heinrich Schuchardt , AKASHI Takahiro , Michal Simek , Francis Laniel , Anand Moon , Marek Vasut , Ilias Apalodimas , Masahisa Kojima , Sean Anderson , Baruch Siach , Yasuharu Shibata , Richard Weinberger , Mikhail Kshevetskiy , u-boot@lists.denx.de Subject: [PATCH v6 03/12] net/tcp: put connection specific data into a tcp_stream structure Date: Tue, 10 Sep 2024 01:27:11 +0300 Message-ID: <20240909222720.2563118-4-mikhail.kshevetskiy@iopsys.eu> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240909222720.2563118-1-mikhail.kshevetskiy@iopsys.eu> References: <20240909222720.2563118-1-mikhail.kshevetskiy@iopsys.eu> X-ClientProxiedBy: FR0P281CA0178.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:b4::6) To GV2PR08MB8121.eurprd08.prod.outlook.com (2603:10a6:150:7d::22) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: GV2PR08MB8121:EE_|DB9PR08MB8722:EE_ X-MS-Office365-Filtering-Correlation-Id: a3cb73fa-98a2-4d8b-a349-08dcd11e9928 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|52116014|1800799024|366016|38350700014|921020; X-Microsoft-Antispam-Message-Info: V+jgwMYJDI2lbBh8cibo2JY8YEjGTJhSMrySEyey4tYvjJTs+I4rgZVSehc5/ZjfbTch141JeK4ENeKEqNeCW1l65UWCBb/9NnSHZpgwUIB34ZR0rvkqynHvD4B/5DjUvPp8Cg38k7s8q2tLQKRWG3df9sNciqJFF0e1pkevoTfF5UXNREVlCHWnelqAmghfmXVJ6p4u9r7Unm/gBEKg1ATrtIFPRGTjZIHQmDcxqb1zYauqOKmlmN8UBgzbeYVmrAH2mFdvFLJVubal/cP1wZPcBI9APmiKPNUx3SvHjHrLeNJGvsHTupqk4BcQGlUggD87OOqY1ZfTQDuHAGLAg7O5Nb3IQLcd51RwoGLTbbGlWteUSk6iOeHDMLjjuvkbpFFUEir9IlZdwiQel0oNECdQ07yn7I5DMP1qDcZdHs/AfMhw7/AlbxgGjq3im4JiYC+wqWMJdHiY3hefzgMsJv/tw/80MInugCoKIND+faDpT4kGPo2MDM/EL/pBQ23yFNssHSwYpMX/Bvz6ur+uMWxv9fWsYwq8mcjV26FIfnC1L2cRhZd7bQZyVNd/tX62rhRDNk7Zo1n8Z3xwA7AI1tbGRjtgw4QydCrP+R8xozXW5ipyFvdb6gr59GlLasWYqDntipnVE2ngVM17ZKeL4ZIEtOuiWfssrR+f6NkBo5oGHcvwXFZA8yaEYOvHQYHROChOhByU5bCJZR9s3eiqyfJ8aclqehS9o8SMyfzh0sKg7zebC1Mq8DIG+/eCA6/RXm8nQ8g8hWY9v8fGT4zQj5KWc0OfspywRNoqPPqRIjZYDxkXxFpRQF7WfAZr0fmzx3+fHhxcvUjye5rf6GDMbjM3d5atwg0E0aqwRVN67CXMBQ8EebeZ5YcWZaBJWNV18SGTG6vwWq8hB5Y8vfp3sx/+zyUZHOi/AbVhqSUHjoq+QR53b9tAaOodCSqcc9KgxuvPg5nRI/ehpfC7AWzq1NnXsjyas4rSlU+hnzxdtzlP9F865yj7YbjOZ4gUwoJW2ZB+5NEWnqXOWExRR2GJz/U8MCEK4+GlD1+IeJJbtKeIDbxONvQWyBmhUVVpHwvELqyxynGVO7f7NW1h3WsXxiOV/JLGKb48I9IN8dgHANMNZpLg5koemt8iq0h5Pfx2sP5ziN3sDX4c6thIiotCv2rxt6/uHgjvfzYYtFbmpA7Qgom+VrvRukVFnDZABNGTdlovL4HG2xsrStghbVV+vPQ0haWDZlrD6uLzcCIPnRCajneM9UCVu9/2BSljKJjZjhcWRsX+hTKHM7IR4pW5PAYKsvcKRj74ECDVi1eygLTXfQ+gegmtyqIcsZsHHRkkupzdJRSab1pFdektQCfdFP0oJNWxxqas4dB00yJYuRdksawbI0C9mv2aa3y0VrnCTjJAvB6fWTIlokpkRVhhB1GIBdy/M3GEaKICq4R68r4= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:GV2PR08MB8121.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(376014)(7416014)(52116014)(1800799024)(366016)(38350700014)(921020); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: vdQ9PdjgqKx+P382yMM/6WtzNCAgzOLmmuB/Na1oOaujJGyY0N3ywVDp5x3wxO/VKKD8nWk9a47CpJSc6UJsWpoY0gee0eOkorE/cnJVJHpYFct+TD1Io2HRb7qvFa7kz4COarIXH9XseBME6TxjjdgzBfu30i0W/j4LvZ1Md3QFDo8fRTzNK2D4gu8jekysX/IGOK6TypaGQfZ2vrVJEN0oPM2RCvtvOpTR962B++bVhlPvdm0PrIxE4CuZnVGAkJFQSFKlBV5iFLDdxtOMYeF/EAZNQ4kxz5jrRv3qxCqEMhBtBYPSkAzM4rvsJNPxBVAVLza2/KMNDvssBCz07FoV0hoVGT14LdCwZkdp2pPZKDSqIX7xNBHx9kbPNAec7w0zPG6vD/dCPYU9j8qpboWJ/BLxtUy0pjQ03VzP2c8nUgcNxhZ1SIb239DXW0H3vlVSSRS0aEclnN7j1syk43XVvZmzVXKYjAvfAY6dUVtPnwh8zcAwyS3Uyn9YxCdk+iY9brP4FWCMo2KkVB6iJPbHD+5jKQkIKb2HPV+kwGMQP7Jj71R4JJVhH51wdbXfcdm67b8Hp1LI7wVDRG2RfaYk94D+JZwkHnPZIS7JwE+ANC7+wLKoXXfxAdWlWqNjN5oEk906RYn7dnzW6jW64KpbEigPSZgM4JPGOofQndOvqrbkoJkNYXMHWMUTnvnbTPyE5els8VnG7PqTV/RPwsaGEt/7jqYhdFjaPQzmBMwnXt4hEGtpo5UyDiBh9qWnNLaFwNjZ3pFScvofEmPdzAphzwX5tzhDT5fc011F5QjmZk2kGmNo/x5pOmlnNq51UZcKs6hf5nYvYtbJpqGYfkiGDl4v0N9kUp9huOl9vkWvVlHyLkWuXVuUwss29z0CBiT7VYLRJ4ILL3vvL+pDCK92cD6o6txZEM/m7Gj8yP4NQOAyR2E4ghKCN+79t/aGFGzAVGYwTb9NbrsMsYsxET8WM7Pc5XAmUZEtoMcUL+tPz+AGcaNmtQ8r95HX6Y9rp7I0ye6mF+4Fl0+0ypyzQOimknRMLuIK2aclrgfBXB7MvQFUvdNxfhNEa5aAG5jcxmkmEwb+rLu1YvMldY3muHysRkmVeWNgZZJA+DbEAzcD/TTcwtMyCdo+Zd3RDrvWf92wbSxU+Kl9Ws5rdPwyIjjl9HkxlWQYNyDVhVgj9KnvhTtib6ZymX+xQc1d7TZDajSdd7y34bRgIuyvWD1EF/hTGsr7nT7hzF6a9faUFEP6CIHGfDgq/VDNm89poGTRCQk+W25jaYUFSefXC5kJVUC9PGLKaoLZ+y2+wyh4fZZRzNkUddm3yfuKYBr3VyqAu19q7yXcPutUPZXPqmadgevl1U7kTORvG6oFxkxi/7XceZUsy1yH1V3l28nA9i+tPYrdBZADZjYtfxvLYGNyNpHtrBl1NlIVr67UAgVkswtK31YSqNwLcMycjRiF7bWuo2Y+4DHugJYyejQ4MTaOXJUfDbDSI/9AwMmUQ84Yd9jZRLh1Tyte9qkJ1ZU8QdJjHjLBHY6HLZBG4uLXuH7fZiXWVnGE4IMpGZZs7vwOCTk+LKDRHHrNQshSkZnqECa0lp0igYWgrvkQVxLfpfNaww== X-OriginatorOrg: iopsys.eu X-MS-Exchange-CrossTenant-Network-Message-Id: a3cb73fa-98a2-4d8b-a349-08dcd11e9928 X-MS-Exchange-CrossTenant-AuthSource: GV2PR08MB8121.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Sep 2024 22:27:32.9890 (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: knG8kCxMRJTyNOmsah+LW3j/reAd+prD3SzO7iG0mmO7G3W/pbs6g0EXfeRB70YsM5I9i/cW+XJJcroAndwKUsZmVyJr+p2gfxOnRbL3894= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB8722 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++;