From patchwork Thu Aug 7 18:29:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jon Chiappetta X-Patchwork-Id: 4360 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd13:b0:671:5a2c:6455 with SMTP id cw19csp1055577mac; Thu, 7 Aug 2025 11:30:25 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXrKki9gMKQSRRy290txuv0Jrvf9QToxBo4zc8Oyxz9XW9J2rGHkOO4ZANqyfZOLNZ5zfr2zTVIdqg=@openvpn.net X-Google-Smtp-Source: AGHT+IGuIPNuO+Hp8Wghunkx/cDJs+P0jzireXsxcDB5D6zCnXROnLhXY2DLKexK+2HSTn5R5DPe X-Received: by 2002:a05:6808:1821:b0:433:fd1b:73f1 with SMTP id 5614622812f47-43597b56374mr241563b6e.6.1754591425016; Thu, 07 Aug 2025 11:30:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1754591425; cv=none; d=google.com; s=arc-20240605; b=gxvkYAub8UJJdruaPS1n/IgI9C0Iju2kClV0vGclr0LkylASiChIfyjhRIaF4kZ9Qk koPKw+m7IRqhjru2AalCMfyCtRPJZAHaExJxwzMS7MHCx4tWtF0TOgoysyVOio1M427M ThldC4cjfiELB8Yp8QSm8e9hq9oB3580IWn4uBF35KRMVFjqWbJZ2PlQ8pkwTATxy2uB xuwk9lxRsxFAT/etFMdnbQ5RxqrdtySwPbvtuA4DxSS1unnBUcy44WQK4oyMKgTHceAG 7Qgc8955/oGa8ysuiurq0isXpeK5MxLqjGDGxH5fTz0Vkij7R4u+eg1MjlVqXuWkTlYl ez5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:references :to:message-id:date:mime-version:dkim-signature:dkim-signature :dkim-signature:dkim-signature; bh=pTgHg0pwvofEx9UzvLT286yZNOYoCYqPXe1KWxwFO9A=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=EbBCUxgl5ckGtUmLF32MnHAmLrQaqk0kHzTZmxAM5xq7v+8eqN90crd3YmLCy1IuP5 m/HjQMTeuri7L3jr8pH5U1/IuZkLqpdazSTOiuiDP/lpFNCZf9b2aeqMSbD9Axp1XAU8 73MxwcudvvqQNDn9NhJFqBTinpqpJA9UsrhA4sG3aW7Ipbw5q9XroSea8cR+E4wZqzll cS8iIYRbSyf/WkWbRKXpnhC6ajBjUffJmbnxOSmb7es65KJPKfAMMNDxLADTCTCJPB70 cRLLGymr7eyt1ai0MbfYs7RzwqLVQsqxK1r3e1Gf+qmZTRFUsyk4gk4u4wb322MlixBj nW4w==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=DmlQzUnw; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=b49taxpo; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=GUvvd6yo; dkim=neutral (body hash did not verify) header.i=@yahoo.com header.s=s2048 header.b=hkh3gCCn; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 5614622812f47-435764dabc9si1354806b6e.319.2025.08.07.11.30.24 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Aug 2025 11:30:24 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=DmlQzUnw; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=b49taxpo; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=GUvvd6yo; dkim=neutral (body hash did not verify) header.i=@yahoo.com header.s=s2048 header.b=hkh3gCCn; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=lists.sourceforge.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Type:Reply-To:From:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Subject:References: To:Message-ID:Date:MIME-Version:Sender:Cc:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Owner; bh=pTgHg0pwvofEx9UzvLT286yZNOYoCYqPXe1KWxwFO9A=; b=DmlQzUnwLy8kP/m4hDKsN5ZHEq nIl1DUHtUc9VoAG5RCNeqFAhg7tFS5n/TC+wwolSc9kPSQECdv6BWCXT5H8zLDSo44c8Xlln64ZqX fVAHSjqTHx1sRZo2AqpaBmrcz4c6rmqrVvC5itV22VNmcIpdFlKBh/gFpPyEEZzYwUcM=; Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1uk5NZ-0002sw-V6; Thu, 07 Aug 2025 18:30:17 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1uk5NY-0002so-II for openvpn-devel@lists.sourceforge.net; Thu, 07 Aug 2025 18:30:16 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:Content-Type:To:Subject:Message-ID:Date: From:MIME-Version:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=os4YZ9R6iqcN4v6H1vjf5guh6UOsj/dWlHCPJrid4HY=; b=b49taxpok9+IvvpOAI73JB84dQ 7QzNLU/A/DHiOnL6TU9fpEUOBPwGU8gDtxzt6rmJdrsKc7lzOn8FT9mw1S8llweQ8bwaXlZd/h0gr r9sbr34qBYQxdUXVYwRm9gSm5Sr1/55Np9gXNnlI01u3un+fii1XJ3fB+Oc5KkauJu1Y=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:Content-Type:To:Subject:Message-ID:Date:From:MIME-Version: Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=os4YZ9R6iqcN4v6H1vjf5guh6UOsj/dWlHCPJrid4HY=; b=G Uvvd6yoGLnj6j3ZUwtZkEz8Ds6Ilqhl1bPkFaUZ7JSgnpMQOcMMGAZsIgCrt4mYFo/sEGXCeOTVte Q9dSqBHOW0PH5kw4KfX+KEw4195IH/PTr5U0qmHyrJMGLtXqDQh4pzfwsnIgxdUl/8AKN/K23OumV KQQeKC9BMFw5wz1c=; Received: from sonic304-9.consmr.mail.bf2.yahoo.com ([74.6.128.32] helo=sonic.asd.mail.yahoo.com) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1uk5NV-0000bL-Qk for openvpn-devel@lists.sourceforge.net; Thu, 07 Aug 2025 18:30:16 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1754591402; bh=os4YZ9R6iqcN4v6H1vjf5guh6UOsj/dWlHCPJrid4HY=; h=From:Date:Subject:To:References:From:Subject:Reply-To; b=hkh3gCCnuBrX5a9ZS4UdbSA6F9QiSdzSeqtEyrJhmxwZWIdiZYz8nF8RsXMoOcMy1JunSlnacuFrj/rH4FgCxVK2iLV+aO3mpHy97y2agG6UWMDrGImqZoCXj/u3kakujDQJE+W4NR37n+v6ZiUU/MmljxrOimNWnncoX28v/ymK7LCsl0C3/sbJYxQbmER7in1xJdEkNpg6119/LhZ1ui56rLqmoMUd9AwYKIXJZE8y+pfsV/yBLcUn0BjnV+5oSKCVlz/Iu5hNVnocd+ZrHseXSz+3bX+NFrgY8zF94duka1CZFcjGwSSouvXPBSUmZfUAL37QqEB+OXtrtVf1mQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1754591403; bh=eyyOP2eqtjMAZllSE1c2+Bhu4cCfXfoKi0ioXp8KPVX=; h=X-Sonic-MF:From:Date:Subject:To:From:Subject; b=fFhfbDvQVlztSVWWcClcM1AcT2+h5U8j7aYqPAsYV5xPyK/VbqhSyg5aYY2faI689JdyUMMSCjUQM+soPafMaz49dZCGxg9DW6+BXZxWhAMSWA8ZTG5IPHiQQMrov5Uz3uE+Mv0UWUPQXb9L2Ezk7q9QTmMfScsxpFl5h4x8dauCTLM1YKFMDV3UV8SDZdt+jScsE2OS+RWhPDtFcbmlf1tlaV0hNLbR2Ny9MNtxOB+Z9Uu1+2hEwzsdRwdRshB5tjxOGGKRpOTmcb4GawRW69T09oeDXoTENvodOTRUfqLeQQNmJ+xej1FyrC+rv4Thm4bjNS6VN2G5gLyRGsekzw== X-YMail-OSG: 2ClSrzQVM1lN2Yavk3vup7p_RrbRpqZdgYPJHsEa7gPEH8Zbfm3HakLpwjBnhK1 YKj2TVXoSwqcWFhIMULjyssDnUYBCV_yaLQYq0fVbrgw0nsJ81f813fFKrOu0.X0CO5E5ChqmGSB wEbz6aOKPlNp95zqA4ZEC4ICk2qPS7GLojlpXVbd7z0oSTXv66QzWjhFKtKh45PFcAXhgx3Wmhu0 rtRGZUjRBySa75heTfv2LBvVQRhg_TaQzYisEsC6rgYRyLcuFaZ_ZwUg_CFrLUpxeA00ZaRiR5O2 yHc4Fluq9d1ZTdvM9l7ULSKqAXtIUJd1yFdo4ErEoQ0Xh5pMA2Gn72o.I0Vt0z.ZnO6mkMHZ2nKb C1BvjYJhvbuET7lbY62wToxXgtl38FIbMaWVMVXyjL8x2O01j7UEMvQ_5kOTrxtdXBQaxdSeQZWz KY0.LoIKtIVpoNYrN3egV1Et4ssYJeVDT2ttzZDcjpt7OTXcWBG2NIUCGfxXqhZMU_nfI9zHgT1S 9zwu.pZnkxyMvT8pADFifbZr9jGzzbGP42bKlaQtzZvqVnI15hZHBQh9xBZidqSD9u8nKa1m1xMb mEfPFQ0sM7.OaRhGXTbgV4xtwRH8IAUiBrKROZ65877F9uoxxiou_FtQiIcCG03b0Fw7qhn_RiFk sp8DCPdPkGgC0CZuVqNn8yply18is._RAWVl5xnRgiDPqx.8WLSmANv.2DrRIXwi1YXkGjWUgnAX snUh2eFjg2zP0SB3OOwIlxVj9pcefXC52q79kd.Rei9Dtw0Q3kXmWoDmAoWL5u.WZY_C_Xt5sbFh YmjA9n6qIWeOc2VKkpYIhtpNHyBugwtnOAHV.X9Ws77kR.lDEWm4dc5A0yCr.5YBGGXAkxm5LE8d ULtYLpQRkCUIMBOQyKfBrsCpAnKnZ4u.sB_1dFF.0yU8arax4Rnv61OI1tUoXbdzm0WBpDBG92tp ffEh0G1vIC9ol_WRW5MXZyQuHZI1z0Tvvc.mBS7brLSWIVgVXlEspyi7_wl8JqGimkK_b2DTOFjt iGOo7ipV1UzB5Brl_wfcVL0PGMSg49rhtd4Nqn2s8ZQ6k8JpeZ26sw.MYRWxEi8RNH2_j07Jkzip jxDl8fAoJP732v47PIdsLCq0BKFf6IeE_Ovbh81ZJz8zFhYtp0OOA1hVWvkLNI4QQ4OyzqJCcJO5 u_0sEnkEsLOO414Z56wkj5igM.zdZOtJOrtkmlc2VXNZQqlBKSvPfdgFHg_cYOlhxu0R0SpLVVIo XvyHYVLZdqaUWPpE9AGk2rgVnxgN8go0CemGCZVQW7Pts9tvWekc2QatMrg8HdO0Xq_zkgu.Suoy 8jC09KaYuMOTi2qH8_M48BbLjf..advg05og97DluTqC5Z5f3aSSgzFxG4xHB7t5.IWUyivmBBCP _JtenTOrPXLWDWr4rCqKXZlyiJM_uvdZtGMOujlFDLF4XiPOoz5cGwhYgi.kS_eiVlIlt2CRIiW7 LXwhhsxiSvVIQiJ..To_EWgb4DJmH6.1.Vs2LSHC3gbTZGNRQylLe6GWesNwh4.Ii4Ci0mGtsEE7 C4DLehaV1qF9wfHp4ZlGHAfrXGuN1E1r68WrbqvyGmtmQwY0uBe_KwnoPxCO8M55Y8FlXxdbuhBA 2PbxI8JNdpQekGU46NVoGfxdi1BfRD_sdd0pEKAEcxJW7W2Rw96dO7wa7E5bvvO92IFGcvnZjyEx arXRLfMxzW16WIGVe.tf49ysxWS3Y0I_MBW1yxOjEb26igY1Wxjjo4IzRiMhCALFmh8yWLX2H_ku S4YQBPaqcuNWr7NKOd7.UHOZflGbdwtfDAUcbqn1Ss1oauQjPxXRSjvWomdiXu0feq9V_GHhIhOI YM6lET_SEC2DP8dHbXC_653iHz4Z_qzrieNuALXWQXzvI8cdFA2O92nEiQuX0bUEWqWk_O5VyFTe UJx1WSImdHIeKGK2RZEtm7v4tt_8z_P7CSpRWcUoLVIv6XJyI59CoCubJGysBsw13mYtkvElrOFw JsQ20oNVmktdnwLoiiQIi0Yfw1sRLXuZ3aFnFXOOk0FEm0E3AxDu6YUCmYqzTc6gyV9kQ.h7aiLL cCJIt125yXnFOngeKdmpPuGa95GCpg_M3JaKjk4bMzXPg8h_z1EK3gcJCsRVf5V.zcFNlDYBETVG PtG6GyRPYtIcEs9k5G3OkJHS7JMU7iYwymQscThgAKqIzZ.jvpjhRKNpTINoj_pPRDifWpblHusv mXLqlmCIC_2RgFoAl6QncK37aeUCB.xpZ X-Sonic-MF: X-Sonic-ID: ecb31889-e21d-44e4-8dbd-398430969b0d Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.bf2.yahoo.com with HTTP; Thu, 7 Aug 2025 18:30:02 +0000 Received: by hermes--production-ne1-9495dc4d7-ksk6c (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID c432f72984828b5cd50c66ab676d4201; Thu, 07 Aug 2025 18:30:00 +0000 (UTC) Received: by mail-oi1-f182.google.com with SMTP id 5614622812f47-433f78705feso483677b6e.0 for ; Thu, 07 Aug 2025 11:30:00 -0700 (PDT) X-Gm-Message-State: AOJu0Yy/zALiz4qTMAqVy/EMjalQ/g4qG6hYGkVLktIof7xLjSo67ifF NA3I6bV53YtKonnOCL/kg6Vjwy+W9bNrSWg7w9hCa4c6BChiozZsbcSN3BcnQdc/JNMbKDB3COT N1gZpLTiVKRArY/FkNYlOQyRzlVgAw4Y= X-Received: by 2002:a05:6808:2512:b0:3f9:aeb6:6eac with SMTP id 5614622812f47-43597d9ddbemr197510b6e.30.1754591398613; Thu, 07 Aug 2025 11:29:58 -0700 (PDT) MIME-Version: 1.0 Date: Thu, 7 Aug 2025 14:29:47 -0400 X-Gmail-Original-Message-ID: X-Gm-Features: Ac12FXxeR899c7BYYakwypZqoAKnzCkGT8B_5RbYX4clD-iiIu40KjxqreOfvak Message-ID: To: openvpn-devel@lists.sourceforge.net References: X-Mailer: WebService/1.1.24260 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Content-Length: 59951 X-Spam-Score: 4.2 (++++) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Thanks to Gert's help on this, I was able to finally configure and compile and run and test the bulk mode changes against the latest git source code to ensure everything still works correctly. I also fixed up some other issues like properly freeing the extra buffer allocations and removing the unneeded batched data prefixes and converting a remaining while loop to a max limited for loop and [...] Content analysis details: (4.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid 0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [74.6.128.32 listed in wl.mailspike.net] 0.0 HTML_MESSAGE BODY: HTML included in message 1.7 RAZOR2_CHECK Listed in Razor2 (http://razor.sf.net/) 2.4 RAZOR2_CF_RANGE_51_100 Razor2 gives confidence level above 50% [cf: 100] 0.0 FSL_BULK_SIG Bulk signature with no Unsubscribe X-Headers-End: 1uk5NV-0000bL-Qk Subject: [Openvpn-devel] Bulk mode - Feature request - Patch diff [updated] X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jon Chiappetta via Openvpn-devel From: Jon Chiappetta Reply-To: Jon Chiappetta Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1839822457599594690?= X-GMAIL-MSGID: =?utf-8?q?1839822457599594690?= Thanks to Gert's help on this, I was able to finally configure and compile and run and test the bulk mode changes against the latest git source code to ensure everything still works correctly. I also fixed up some other issues like properly freeing the extra buffer allocations and removing the unneeded batched data prefixes and converting a remaining while loop to a max limited for loop and properly resetting the outgoing tun buffer pointer at the end of the write method when finished. Thanks, Jon C Example updated pull request: https://github.com/OpenVPN/openvpn/pull/814/files git formatted diff patch: From 985e88a9af26a39554f113f37ee18032a2f41c3e Mon Sep 17 00:00:00 2001 From: Jon Chiappetta Date: Wed, 6 Aug 2025 16:33:18 -0400 Subject: [PATCH] bulk mode --- src/openvpn/forward.c | 217 ++++++++++++++++++++++++++++++++++++++++-- src/openvpn/forward.h | 4 + src/openvpn/init.c | 56 +++++++++++ src/openvpn/mtu.c | 10 +- src/openvpn/mtu.h | 13 +++ src/openvpn/multi.c | 7 +- src/openvpn/openvpn.h | 10 ++ src/openvpn/options.c | 8 ++ src/openvpn/options.h | 3 + 9 files changed, 316 insertions(+), 12 deletions(-) -- 2.39.5 (Apple Git-154) diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 75ca9d5c..d9a98607 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -46,6 +46,9 @@ #include "mstats.h" +#include +#include + counter_type link_read_bytes_global; /* GLOBAL */ counter_type link_write_bytes_global; /* GLOBAL */ @@ -78,6 +81,32 @@ show_wait_status(struct context *c) #endif /* ifdef ENABLE_DEBUG */ +bool check_bulk_mode(struct context *c) +{ + if ((c->c2.frame.bulk_size > 0) && (c->c1.tuntap != NULL) && (c->c2.buffers != NULL)) + { + return true; + } + return false; +} + +void xfer_io(struct context *c, struct context *b) +{ + int plen = 0; + if (check_bulk_mode(b)) + { + int leng = (b->c2.buffers->bufs_indx + 1); + for (int x = 0; x < leng; ++x) + { + plen = BLEN(&b->c2.bufs[x]); + if (plen < 1) { c->c2.bufs[x].len = 0; } + else { c->c2.bufs[x] = b->c2.bufs[x]; } + } + c->c2.buffers->bufs_indx = b->c2.buffers->bufs_indx; + b->c2.buffers->bufs_indx = -1; + } +} + static void check_tls_errors_co(struct context *c) { @@ -605,6 +634,21 @@ buffer_turnover(const uint8_t *orig_buf, struct buffer *dest_stub, struct buffer } } +uint8_t *buff_prepsize(uint8_t *buff, int *size) +{ + buff[0] = ((*size >> 8) & 0xff); + buff[1] = ((*size >> 0) & 0xff); + buff += 2; + return buff; +} + +uint8_t *buff_postsize(uint8_t *buff, int *size) +{ + *size = ((buff[0] << 8) + (buff[1] << 0)); + buff += 2; + return buff; +} + /* * Compress, fragment, encrypt and HMAC-sign an outgoing packet. * Input: c->c2.buf @@ -1031,6 +1075,7 @@ process_incoming_link_part1(struct context *c, struct link_socket_info *lsi, boo fprintf(stderr, "R"); } #endif + msg(D_LINK_RW, "%s READ [%d] from %s: %s", proto2ascii(lsi->proto, lsi->af, true), BLEN(&c->c2.buf), print_link_socket_actual(&c->c2.from, &gc), PROTO_DUMP(&c->c2.buf, &gc)); @@ -1211,6 +1256,23 @@ process_incoming_link_part2(struct context *c, struct link_socket_info *lsi, } } +void process_incoming_link_part3(struct context *c) +{ + int leng = BLEN(&c->c2.to_tun); + if (leng > 0) + { + if (check_bulk_mode(c)) + { + c->c2.buffers->send_tun_max.offset = TUN_BAT_OFF; + c->c2.buffers->send_tun_max.len = leng; + bcopy(BPTR(&c->c2.to_tun), BPTR(&c->c2.buffers->send_tun_max), leng); + //dmsg(M_INFO, "FWD BAT LINK 0 [%d] [%d] [%d] [%d] [%d]", BLEN(&c->c2.buf), BLEN(&c->c2.to_tun), BLEN(&c->c2.buffers->read_link_buf), BLEN(&c->c2.buffers->read_link_buf), BLEN(&c->c2.buffers->send_tun_max)); + c->c2.to_tun.offset += 2; + c->c2.buf.offset += 2; + } + } +} + static void process_incoming_link(struct context *c, struct link_socket *sock) { @@ -1221,6 +1283,7 @@ process_incoming_link(struct context *c, struct link_socket *sock) process_incoming_link_part1(c, lsi, false); process_incoming_link_part2(c, lsi, orig_buf); + process_incoming_link_part3(c); perf_pop(); } @@ -1321,7 +1384,7 @@ process_incoming_dco(struct context *c) */ void -read_incoming_tun(struct context *c) +read_incoming_tun_part2(struct context *c) { /* * Setup for read() call on TUN/TAP device. @@ -1382,6 +1445,55 @@ read_incoming_tun(struct context *c) perf_pop(); } +void read_incoming_tun_part3(struct context *c) +{ + fd_set rfds; + struct timeval timo; + if (check_bulk_mode(c)) + { + int plen = 0; + int fdno = c->c1.tuntap->fd; + for (int x = 0; x < TUN_BAT_MAX; ++x) + { + int leng = plen; + int indx = (c->c2.buffers->bufs_indx + 1); + if (indx >= TUN_BAT_MIN) { break; } + if (leng < 1) + { + FD_ZERO(&rfds); + FD_SET(fdno, &rfds); + timo.tv_sec = 0; + timo.tv_usec = 0; + select(fdno+1, &rfds, NULL, NULL, &timo); + if (FD_ISSET(fdno, &rfds)) + { + read_incoming_tun_part2(c); + plen = BLEN(&c->c2.buf); + } else { break; } + } + //dmsg(M_INFO, "FWD BAT READ 0 [%d] [%d] [%d] [%d] [%d]", c->c2.buffers->bufs_indx + 1, fdno, BLEN(&c->c2.buf), BLEN(&c->c2.buffers->read_tun_buf), BLEN(&c->c2.buffers->read_tun_max)); + leng = plen; + if (leng > 0) + { + c->c2.buffers->read_tun_bufs[indx].offset = TUN_BAT_OFF; + c->c2.buffers->read_tun_bufs[indx].len = leng; + bcopy(BPTR(&c->c2.buf), BPTR(&c->c2.buffers->read_tun_bufs[indx]), leng); + c->c2.bufs[indx] = c->c2.buffers->read_tun_bufs[indx]; + c->c2.buffers->bufs_indx = indx; + } else { break; } + plen = 0; + } + } +} + +void read_incoming_tun(struct context *c) +{ + if (c->c2.frame.bulk_size <= 0) { + read_incoming_tun_part2(c); + } + read_incoming_tun_part3(c); +} + /** * Drops UDP packets which OS decided to route via tun. * @@ -1469,7 +1581,7 @@ drop_if_recursive_routing(struct context *c, struct buffer *buf) */ void -process_incoming_tun(struct context *c, struct link_socket *out_sock) +process_incoming_tun_part2(struct context *c, struct link_socket *out_sock) { struct gc_arena gc = gc_new(); @@ -1488,7 +1600,7 @@ process_incoming_tun(struct context *c, struct link_socket *out_sock) #endif /* Show packet content */ - dmsg(D_TUN_RW, "TUN READ [%d]", BLEN(&c->c2.buf)); + dmsg(D_TUN_RW, "TUN READ [%d] [%d]", BLEN(&c->c2.buf), c->c2.frame.buf.payload_size); if (c->c2.buf.len > 0) { @@ -1512,7 +1624,9 @@ process_incoming_tun(struct context *c, struct link_socket *out_sock) } if (c->c2.buf.len > 0) { + if ((c->c2.buffers == NULL) || (c->c2.buffers->flag_ciph != -2)) { encrypt_sign(c, true); + } } else { @@ -1522,6 +1636,60 @@ process_incoming_tun(struct context *c, struct link_socket *out_sock) gc_free(&gc); } +void process_incoming_tun_part3(struct context *c, struct link_socket *out_sock) +{ + if (check_bulk_mode(c)) + { + c->c2.buffers->flag_ciph = -2; + c->c2.buffers->read_tun_max.offset = TUN_BAT_OFF; + c->c2.buffers->read_tun_max.len = 0; + uint8_t *temp = BPTR(&c->c2.buffers->read_tun_max); + int plen = 0, fdno = c->c1.tuntap->fd; + int maxl = 0, leng = (c->c2.buffers->bufs_indx + 1); + if ((fdno > 0) && (leng > 0)) + { + for (int x = 0; x < leng; ++x) + { + c->c2.buf = c->c2.bufs[x]; + //dmsg(M_INFO, "FWD BAT INPT 0 [%d] [%d] [%d] [%d] [%d]", x, fdno, BLEN(&c->c2.buf), BLEN(&c->c2.buffers->read_tun_buf), BLEN(&c->c2.bufs[x])); + process_incoming_tun_part2(c, out_sock); + if (BLEN(&c->c2.buf) < 1) + { + c->c2.bufs[x].len = 0; + } + } + for (int x = 0; x < leng; ++x) + { + plen = c->c2.bufs[x].len; + if (plen > 0) + { + temp = buff_prepsize(temp, &plen); + bcopy(BPTR(&c->c2.bufs[x]), temp, plen); + temp += plen; maxl += (plen + 2); + } + } + if (maxl > 0) + { + c->c2.buffers->read_tun_max.offset = TUN_BAT_OFF; + c->c2.buffers->read_tun_max.len = maxl; + c->c2.buf = c->c2.buffers->read_tun_max; + //dmsg(M_INFO, "FWD BAT INPT 1 [%d] [%d] [%d] [%d] [%d]", maxl, fdno, BLEN(&c->c2.buf), BLEN(&c->c2.buffers->read_tun_buf), BLEN(&c->c2.buffers->read_tun_max)); + encrypt_sign(c, true); + } + } + c->c2.buffers->bufs_indx = -1; + c->c2.buffers->flag_ciph = -1; + } +} + +void process_incoming_tun(struct context *c, struct link_socket *out_sock) +{ + if (c->c2.frame.bulk_size <= 0) { + process_incoming_tun_part2(c, out_sock); + } + process_incoming_tun_part3(c, out_sock); +} + /** * Forges a IPv6 ICMP packet with a no route to host error code from the * IPv6 packet in buf and sends it directly back to the client via the tun @@ -1748,7 +1916,7 @@ process_outgoing_link(struct context *c, struct link_socket *sock) perf_push(PERF_PROC_OUT_LINK); - if (c->c2.to_link.len > 0 && c->c2.to_link.len <= c->c2.frame.buf.payload_size) + if (c->c2.to_link.len > 0 && (c->c2.to_link.len <= c->c2.frame.buf.payload_size || c->c2.frame.bulk_size > 0)) { /* * Setup for call to send/sendto which will send @@ -1793,6 +1961,7 @@ process_outgoing_link(struct context *c, struct link_socket *sock) fprintf(stderr, "W"); } #endif + msg(D_LINK_RW, "%s WRITE [%d] to %s: %s", proto2ascii(sock->info.proto, sock->info.af, true), BLEN(&c->c2.to_link), print_link_socket_actual(c->c2.to_link_addr, &gc), PROTO_DUMP(&c->c2.to_link, &gc)); @@ -1892,7 +2061,7 @@ process_outgoing_link(struct context *c, struct link_socket *sock) */ void -process_outgoing_tun(struct context *c, struct link_socket *in_sock) +process_outgoing_tun_part2(struct context *c, struct link_socket *in_sock) { /* * Set up for write() call to TUN/TAP @@ -1912,7 +2081,7 @@ process_outgoing_tun(struct context *c, struct link_socket *in_sock) process_ip_header(c, PIP_MSSFIX | PIPV4_EXTRACT_DHCP_ROUTER | PIPV4_CLIENT_NAT | PIP_OUTGOING, &c->c2.to_tun, in_sock); - if (c->c2.to_tun.len <= c->c2.frame.buf.payload_size) + if (c->c2.to_tun.len <= c->c2.frame.buf.payload_size || c->c2.frame.bulk_size > 0) { /* * Write to TUN/TAP device. @@ -1925,7 +2094,8 @@ process_outgoing_tun(struct context *c, struct link_socket *in_sock) fprintf(stderr, "w"); } #endif - dmsg(D_TUN_RW, "TUN WRITE [%d]", BLEN(&c->c2.to_tun)); + + dmsg(D_TUN_RW, "TUN WRITE [%d] [%d]", BLEN(&c->c2.to_tun), c->c2.frame.buf.payload_size); #ifdef PACKET_TRUNCATION_CHECK ipv4_packet_size_verify(BPTR(&c->c2.to_tun), BLEN(&c->c2.to_tun), TUNNEL_TYPE(c->c1.tuntap), @@ -1981,6 +2151,39 @@ process_outgoing_tun(struct context *c, struct link_socket *in_sock) perf_pop(); } +void process_outgoing_tun_part3(struct context *c, struct link_socket *in_sock) +{ + if (check_bulk_mode(c)) + { + int maxl = 0, plen = 0; + int leng = BLEN(&c->c2.buffers->send_tun_max); + uint8_t *temp = BPTR(&c->c2.buffers->send_tun_max); + for (int x = 0; x < TUN_BAT_MAX; ++x) + { + temp = buff_postsize(temp, &plen); + if ((leng > 0) && (plen > 0) && ((maxl + plen) < leng)) + { + c->c2.to_tun = c->c2.buffers->to_tun_max; + c->c2.to_tun.offset = TUN_BAT_OFF; + c->c2.to_tun.len = plen; + bcopy(temp, BPTR(&c->c2.to_tun), plen); + temp += plen; maxl += (plen + 2); + //dmsg(M_INFO, "FWD BAT OUTP 1 [%d] [%d] [%d] [%d]", x, BLEN(&c->c2.buf), BLEN(&c->c2.to_tun), BLEN(&c->c2.buffers->read_link_buf)); + process_outgoing_tun_part2(c, in_sock); + } else { break; } + } + buf_reset(&c->c2.to_tun); + } +} + +void process_outgoing_tun(struct context *c, struct link_socket *in_sock) +{ + if (c->c2.frame.bulk_size <= 0) { + process_outgoing_tun_part2(c, in_sock); + } + process_outgoing_tun_part3(c, in_sock); +} + void pre_select(struct context *c) { diff --git a/src/openvpn/forward.h b/src/openvpn/forward.h index d5641491..9fda1583 100644 --- a/src/openvpn/forward.h +++ b/src/openvpn/forward.h @@ -79,6 +79,8 @@ void pre_select(struct context *c); void process_io(struct context *c, struct link_socket *sock); +void xfer_io(struct context *c, struct context *b); + /**********************************************************************/ /** @@ -196,6 +198,8 @@ bool process_incoming_link_part1(struct context *c, struct link_socket_info *lsi void process_incoming_link_part2(struct context *c, struct link_socket_info *lsi, const uint8_t *orig_buf); +void process_incoming_link_part3(struct context *c); + /** * Transfers \c float_sa data extracted from an incoming DCO * PEER_FLOAT_NTF to \c out_osaddr for later processing. diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 40ae2c8c..0849dfce 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2971,6 +2971,10 @@ frame_finalize_options(struct context *c, const struct options *o) tailroom += COMP_EXTRA_BUFFER(payload_size); #endif + if (frame->bulk_size > 0) { + payload_size = frame->tun_mtu; + } + frame->buf.payload_size = payload_size; frame->buf.headroom = headroom; frame->buf.tailroom = tailroom; @@ -3473,6 +3477,9 @@ do_init_frame_tls(struct context *c) if (c->c2.tls_multi) { tls_multi_init_finalize(c->c2.tls_multi, c->options.ce.tls_mtu); + if (c->c2.frame.bulk_size > 0) { + c->c2.tls_multi->opt.frame.buf.payload_size = c->c2.frame.tun_mtu; + } ASSERT(c->c2.tls_multi->opt.frame.buf.payload_size <= c->c2.frame.buf.payload_size); frame_print(&c->c2.tls_multi->opt.frame, D_MTU_INFO, "Control Channel MTU parms"); @@ -3536,6 +3543,14 @@ do_init_frame(struct context *c) c->c2.frame.extra_tun += c->options.ce.tun_mtu_extra; } + /* + * Adjust bulk size based on the --bulk-mode parameter. + */ + if (c->options.ce.bulk_mode) + { + c->c2.frame.bulk_size = c->options.ce.tun_mtu; + } + /* * Fill in the blanks in the frame parameters structure, * make sure values are rational, etc. @@ -3676,9 +3691,40 @@ init_context_buffers(const struct frame *frame) size_t buf_size = BUF_SIZE(frame); + if (frame->bulk_size > 0) { + buf_size = BAT_SIZE(TUN_BAT_MAX, frame->tun_mtu, frame->buf.headroom + frame->buf.tailroom); + } + + dmsg(M_INFO, "MEM NEW [%ld] [%d+%d+%d]", buf_size, frame->buf.headroom, frame->buf.payload_size, frame->buf.tailroom); + b->read_link_buf = alloc_buf(buf_size); b->read_tun_buf = alloc_buf(buf_size); + if (frame->bulk_size > 0) { + for (int x = 0; x < TUN_BAT_MAX; ++x) + { + size_t part_size = BUF_SIZE(frame); + b->read_tun_bufs[x] = alloc_buf(part_size); + b->read_tun_bufs[x].offset = TUN_BAT_OFF; + b->read_tun_bufs[x].len = 0; + } + + b->read_tun_max = alloc_buf(buf_size); + b->read_tun_max.offset = TUN_BAT_OFF; + b->read_tun_max.len = 0; + + b->send_tun_max = alloc_buf(buf_size); + b->send_tun_max.offset = TUN_BAT_OFF; + b->send_tun_max.len = 0; + + b->to_tun_max = alloc_buf(buf_size); + b->to_tun_max.offset = TUN_BAT_OFF; + b->to_tun_max.len = 0; + } + + b->bufs_indx = -1; + b->flag_ciph = -1; + b->aux_buf = alloc_buf(buf_size); b->encrypt_buf = alloc_buf(buf_size); @@ -3701,6 +3747,16 @@ free_context_buffers(struct context_buffers *b) free_buf(&b->read_tun_buf); free_buf(&b->aux_buf); + if (b->to_tun_max.data) { + free_buf(&b->to_tun_max); + free_buf(&b->send_tun_max); + free_buf(&b->read_tun_max); + for (int x = 0; x < TUN_BAT_MAX; ++x) + { + free_buf(&b->read_tun_bufs[x]); + } + } + #ifdef USE_COMP free_buf(&b->compress_buf); free_buf(&b->decompress_buf); diff --git a/src/openvpn/mtu.c b/src/openvpn/mtu.c index a419e32d..7e35c837 100644 --- a/src/openvpn/mtu.c +++ b/src/openvpn/mtu.c @@ -41,9 +41,15 @@ void alloc_buf_sock_tun(struct buffer *buf, const struct frame *frame) { /* allocate buffer for overlapped I/O */ - *buf = alloc_buf(BUF_SIZE(frame)); + size_t alen = BUF_SIZE(frame); + size_t blen = frame->buf.payload_size; + if (frame->bulk_size > 0) { + alen = BAT_SIZE(TUN_BAT_MAX, frame->tun_mtu, TUN_BAT_OFF); + blen = BAT_SIZE(TUN_BAT_MAX, frame->tun_mtu, TUN_BAT_NOP); + } + *buf = alloc_buf(alen); ASSERT(buf_init(buf, frame->buf.headroom)); - buf->len = frame->buf.payload_size; + buf->len = blen; ASSERT(buf_safe(buf, 0)); } diff --git a/src/openvpn/mtu.h b/src/openvpn/mtu.h index 925ef0bf..eb799fb3 100644 --- a/src/openvpn/mtu.h +++ b/src/openvpn/mtu.h @@ -58,6 +58,14 @@ */ #define TUN_MTU_MIN 100 +/* + * Bulk mode static define values. + */ +#define TUN_BAT_MIN 6 +#define TUN_BAT_MAX 9 +#define TUN_BAT_OFF 256 +#define TUN_BAT_NOP 0 + /* * Default MTU of network over which tunnel data will pass by TCP/UDP. */ @@ -152,6 +160,10 @@ struct frame * which defaults to 0 for tun and 32 * (\c TAP_MTU_EXTRA_DEFAULT) for tap. * */ + + int bulk_size; /**< Signal to the init frame function + * to allow for bulk mode TCP transfers. + * */ }; /* Forward declarations, to prevent includes */ @@ -171,6 +183,7 @@ struct options; * larger than the headroom. */ #define BUF_SIZE(f) ((f)->buf.headroom + (f)->buf.payload_size + (f)->buf.tailroom) +#define BAT_SIZE(a, b, c) ((a * b) + c) /* * Function prototypes. diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index e1ce32ab..9e089703 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -3414,6 +3414,7 @@ multi_process_incoming_link(struct multi_context *m, struct multi_instance *inst } process_incoming_link_part2(c, lsi, orig_buf); + process_incoming_link_part3(c); } perf_pop(); @@ -3558,9 +3559,7 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags const int dev_type = TUNNEL_TYPE(m->top.c1.tuntap); int16_t vid = 0; -#ifdef MULTI_DEBUG_EVENT_LOOP - printf("TUN -> TCP/UDP [%d]\n", BLEN(&m->top.c2.buf)); -#endif + msg(D_MULTI_DEBUG, "TUN -> TCP/UDP [%d]", BLEN(&m->top.c2.buf)); if (m->pending) { @@ -3610,6 +3609,8 @@ multi_process_incoming_tun(struct multi_context *m, const unsigned int mpp_flags { /* transfer packet pointer from top-level context buffer to instance */ c->c2.buf = m->top.c2.buf; + /* todo determine if to call this (multi_process_incoming_tun) for each bulk item read? */ + xfer_io(c, &m->top); } else { diff --git a/src/openvpn/openvpn.h b/src/openvpn/openvpn.h index cd99cd40..21fa8967 100644 --- a/src/openvpn/openvpn.h +++ b/src/openvpn/openvpn.h @@ -112,6 +112,14 @@ struct context_buffers */ struct buffer read_link_buf; struct buffer read_tun_buf; + + struct buffer read_tun_bufs[TUN_BAT_MAX]; + struct buffer read_tun_max; + struct buffer send_tun_max; + struct buffer to_tun_max; + + int bufs_indx; + int flag_ciph; }; /* @@ -376,6 +384,8 @@ struct context_2 struct buffer to_tun; struct buffer to_link; + struct buffer bufs[TUN_BAT_MAX]; + /* should we print R|W|r|w to console on packet transfers? */ bool log_rw; diff --git a/src/openvpn/options.c b/src/openvpn/options.c index c54032d8..041d17d0 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -304,6 +304,7 @@ static const char usage_message[] = " 'maybe' -- Use per-route hints\n" " 'yes' -- Always DF (Don't Fragment)\n" "--mtu-test : Empirically measure and report MTU.\n" + "--bulk-mode : Use bulk TUN/TCP reads/writes.\n" #ifdef ENABLE_FRAGMENT "--fragment max : Enable internal datagram fragmentation so that no UDP\n" " datagrams are sent which are larger than max bytes.\n" @@ -3005,6 +3006,9 @@ options_postprocess_mutate_ce(struct options *o, struct connection_entry *ce) ce->tun_mtu_extra_defined = true; ce->tun_mtu_extra = TAP_MTU_EXTRA_DEFAULT; } + if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_SERVER && ce->proto != PROTO_TCP_CLIENT) { + ce->bulk_mode = false; + } } /* @@ -9926,6 +9930,10 @@ add_option(struct options *options, char *p[], bool is_inline, const char *file, goto err; } } + else if (streq(p[0], "bulk-mode")) + { + options->ce.bulk_mode = true; + } else { int i; diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 38e67c8d..d1b0586d 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -174,6 +174,9 @@ struct connection_entry /* Allow only client that support resending the wrapped client key */ bool tls_crypt_v2_force_cookie; + + /* Bulk mode allows for multiple tun reads + larger tcp writes */ + bool bulk_mode; }; struct remote_entry