From patchwork Wed Aug 6 23:50:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jon Chiappetta X-Patchwork-Id: 4359 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd13:b0:671:5a2c:6455 with SMTP id cw19csp546959mac; Wed, 6 Aug 2025 16:50:56 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWx/9PVchl2Rjxv6Yu2D/q/1PWYCJMyCZGsHujVsQCXquy4da2WqhcgaCcVUlP8/NmU8x1t8LnSuIM=@openvpn.net X-Google-Smtp-Source: AGHT+IGu7sYWByUhVLm0QbSNSreW2WzqLijATokGhj4cg/cx7Cg4tnHZCrjLT1q/ZGaw3BMCrGfM X-Received: by 2002:a4a:e915:0:b0:619:9530:87e3 with SMTP id 006d021491bc7-61b5f2c8a08mr4238166eaf.1.1754524256029; Wed, 06 Aug 2025 16:50:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1754524256; cv=none; d=google.com; s=arc-20240605; b=gB6kbRvxuOJW6bNQw+6k1XC9HfCyBh4+MbgdwnWiF9QlI6ybucaamiqmFO+Ed07Jt9 Ej1JMh6mvh3muep8EFGKyXlp41Eesa4ou5b1umUT/GNLmxax3HRfdhyehuMgGEZ4ZFAV qjfduKMHZGfBF6WMey2cf8DFFNhvSPCUzKaPQjk1rHDaQ6X5i+J0OeUwQTq8TYjJS+8U 0z1gK4BIMYbFu4+Q7JeZtAXm/r2nEh6qAkdVpadWiM4Ch3iq/yMklskhr5QMizt1SLrh vwmtIhLf4HiOenwpgihLGTtzQd8DMibaA9B3kICtu6uM/ak4twhSMoyvzFm9P9eIP41O SpTg== 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=rdNY9DHVkFt5zsn7xcVW0HujA4KbLlNCgdNubjsGeN0=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=a6YDswv5AvRUU2lvicGmobAucrZjOEGJvYZX063wuwgEzrKPnb/yvMMi86r/2vDybs gGIFP0GKkfScItDVlEeVv0Rera/cXBl/tgjiXZoRjtaai+eakkLoYy1xiQFSsH0r1WoI 0hqBX/mONuAtHzr8imOeo2NGtRJu0MctQPnLb9CphGsEwnmhahNyMOU+7+6H4u5S0UNI OPnmvHXnb5AlLQidWH1jwx96rxJNzpmvaUA2UQZ+i1/uGzYPn6dgup7zjfciYq3C5r2L caffGG38ClgnHxKL6aNyVMpt61TrVoYNsAl3pI/h1Z/A3fpqjL6ToswG1p5kPJDO3xyK bXpw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=DklY6WjL; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=NFh51MPC; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=GSWIV6oH; dkim=neutral (body hash did not verify) header.i=@yahoo.com header.s=s2048 header.b=Kkun4LSl; 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 006d021491bc7-619704aa227si3871541eaf.80.2025.08.06.16.50.55 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Aug 2025 16:50:55 -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=DklY6WjL; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=NFh51MPC; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=GSWIV6oH; dkim=neutral (body hash did not verify) header.i=@yahoo.com header.s=s2048 header.b=Kkun4LSl; 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=rdNY9DHVkFt5zsn7xcVW0HujA4KbLlNCgdNubjsGeN0=; b=DklY6WjLPN7P5jYREHJiCghrLQ dB52n1l1ckHcXhgyPwI0kgh4mIh2dsXKHljFMSnh+5pVwnlvHbmXTtOKACLWdDwmGdYYzNun+alhN VX4UwQ3gSMfDIKKT2kmBjJPHSuBWaqwsIZv6ilRZsWg5ASftMu9Za6oNjbzHY25RMG5c=; Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1ujnuC-0008E3-2h; Wed, 06 Aug 2025 23:50:48 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1ujnuA-0008Dw-DG for openvpn-devel@lists.sourceforge.net; Wed, 06 Aug 2025 23:50:47 +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=3W2fPdXO2dY72xznO7yP2zG7X/5/1AA29f+/Wv6/QtA=; b=NFh51MPCXBhUSATiYdBR8qjIGr sqnCFqqLDyd6m7kfRA2ElEfV+/tcGHhNw/ou6AW7vsaukXUbyd7JAMo+sateHST0VSm1p15u4d2Z2 hiXWBEVbp8zzqsD6xU/dPtD8IPUqS4fQt9IdRv0Z23gBcfOoDTOTQEOY+z2NcIPbN6cU=; 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=3W2fPdXO2dY72xznO7yP2zG7X/5/1AA29f+/Wv6/QtA=; b=G SWIV6oHerxDnATuxSGwCkD9hdtLLsGLT3aslXNFO7vpsdTvkdzLhLV9jFYTEjaRvrmurfPDgyg1aO YzW8/p2r4G7VPDxVlrZ3o8paymdTQnQwxzRgBwaRWRw7rs8ColeLJwTXkpId299eJ/Lsq+CIh5N1l 42KUs0bDr4xloh4M=; Received: from sonic304-10.consmr.mail.bf2.yahoo.com ([74.6.128.33] 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 1ujnu8-00010n-Fo for openvpn-devel@lists.sourceforge.net; Wed, 06 Aug 2025 23:50:47 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1754524233; bh=3W2fPdXO2dY72xznO7yP2zG7X/5/1AA29f+/Wv6/QtA=; h=From:Date:Subject:To:References:From:Subject:Reply-To; b=Kkun4LSl6vHjrrvjGTN1AUtdaNbISASGNh4nVIQZUEtmLEVa0d7h4rd8wLXaCnbAmnCqT6jAAgzqCW7T4jxaiGCgigg+h4P/49oWFLb+zODPimTLT1DVvbGvBw0tAwBkac9VQu9F8eyQ1biZY3TyUxh8vzbpVTPr0XA7xtPj58BY8qXER2Pi1xSXUtO5S9tgHjDhgB+IeqmFQXkvzfrFRshR7tzjE71WVXrqEq8w51MmWFzR3Sdxt2F+u8leG0i6FrquY8V+Np+C/bC2mvGwX8JZS0QHJM/kzyZQc39+JmuCzFjpuIJtXSYzX5cK4woPOVQMGsppG+Idvyeov3SJvw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1754524233; bh=vG42AACDFF4S00lM2ZcZqYi+YmOcwwkVJ78ezegLUrW=; h=X-Sonic-MF:From:Date:Subject:To:From:Subject; b=i4xVtV54Ey0Jkvm6HETZq8VMuLnpBZo3nYkJeWRYzTQqnSOa+Wi2h8eNSG10AtrCjzke67On/yi8J/tOBG6BrLfrWEXcBYDZCoOIONf2z5I59wHqAifIVlZAvQdNN1bIXo6lqbH2hO5cnjkgNXyOtj93Ll0mpF/gXOc2meQ/1L39DtWXQeYI5ZWTA2HpHGj2BOAKHEWdKHGnLKEhYEEVSPj4hDhCz5UAqEg1foAWRGC5vWz6YJdOGUq5X+uaK51tZS/PtHeYXjWBbVBR7XLkM5XhHchopqcZc6pTw+Vkbl1a7VlCqYkOuvU5OKicAlPAydq3+2A0zrb948L3vMHtoQ== X-YMail-OSG: sIcbd9AVM1kYwSZkfo8sce5ptl9E2w18Bf87sUeHXzUQZUtLLcaiSnoEnjStIyx CdFAUX3k2zr68r0xThvbS2mEXQsH9TnX7pQLXeYUVjCXetZCyznH8ifwd3b3MT.Dfn.W6GE.6cU1 edavIDaCWu2R.pWr0BIfVw6KMOSvn51CnqVG8_pTdaJO.MC93v7PKoPMZtSVjLGcGX46h8pe8eo1 nF9j3HSUJ8PmM9m9OMvcigy_Pu7DONfrjKfhqQK4AXxBgckC3Sxfb7ReTuVJdLPoydbCH6KG8WuI rKhLTjdkT4PaNYIRKla0dpC.5DfWyPTQPHvVyZrPQrWpg64KfaGV1F5NZAsjcVshT9.yFfB2JoAj sjuJrS1NqbXR_3NOv7DwMLpUl3W_7yqBlNv2RnGsq4dalOdmoEJ9dWgA1A6hHQMUxlTUziWJBf3A QAjFf.QRkQLIgmrFSdCJphPhgcyFuwqTC0CPS6HyXliKR0EIz8Z5JdBJE3m2B.c5_M7.3oOx4EhF 0F8ozAv8u5a3y2XXfqyuj_QAdp2mSbkZ7w_W1mNXGWF2raVCgTRah0gGlDDj2PBqUUvF_gocqTmt WRXkG9Zq3vAqtM.evtJoHrOcaCMuX59DQDM_MLhAD8kYCq8bdq9V9Zp3hSaO1wvCZWHpNvTlUuFs fhC1G3sYTclLtRAs_C9xpg7GV26VTRO4Ch0Jtu_h2VxaaBt7L4cyPxMum2orTj7DaKgXeu84utSf 1VI3JSInsdzKObSGUtzUPC5UM4TYTs0Gnsu7zmseQ4ksiYLMcucVAvNzN_n51Szju.YMdbFPauDK ybCRWrl2Gco41ZVdVNHiOJbovNgrAFrT7vrjDXduY1zvMSyfpcueqpJeD_Wsd0zYxfQKmPV.GEif xUTfK04P.FANaWDUKxVryGEHUYcdctOMTwaaZTer2M3cfZaluvj7Xn8Dzund_D6NdPAaB67nnPNh ItnAbns480l4a_zVPhhkfLloWLZTLPbElzc1ODaD9GHk052Gf7Dl0Hmu6KXqXWbcFysf8vslDbB2 CuP1La9w6wHdYKwBS9b0OUNAVzsR45BFdXoM5ECB9hygDGl_T8LZPj02yqP5B9jdzQQdMvT2wkEH p.fcEVhnE6C5rqzbwFMOt6XV9mGRnIw7MDjn3xKvv1nN9fzJWC_tiqUEMADGBOVN7zcxH0gJ7Ibm zowQNezeP18iChedRNThiCOL2nEnxi4TWens.hNeCBdKCOWsh9DP5Zmx8_cSOYKtWuCs_CHDo2dc qG3.CXXhQRLEmU.vr.6bmu6q3crM33vVNHRFFxU4x5RcUtfZb4ne0Ruf.xxJ1pdnz8SSyxPE5pWQ wWDJ_d7M4axXzBN6fwhh_L5mE8Ko37B3oUqEzeC8Um.at0XKt5HuHl8HH2QQxUyj6tuR.F6DpU6Z RizM.a5.IThMSjE5BjDf5VmRc8nZRuryMJuajrWFAONFuhzIYd1dvSm2jBXuTuCLDS.EGYhkAlV3 Q0wVHkzQoKq8yIDNb3Zw6oPRhVCUOGfXlIkGKLvEanxSd7Un7Ft1tB_QB88BCiCc2fWLD_zhBVgh vQAkaYtsbhE2g8.mN1JcYYZUqLKvHSFr4fj3L1LCXWKfThRPDPw1MNl1db9h2SCG5gThu6uRtz3R mMufnJOsZQ6MOlDVpnZbANqlIYpRYOB_4qIdxVmcRQQAhkwVoL4RmjXOdI2JuiHSPHukhcjDXsg2 cMDVgzOQ1a7O.L_xZ0YOdKgNz9f05RnlsdI.w8tM96CTG8O1RQJS6hmNokTl2dP9YUYuZ0990tOb pkIlUKPY8KG5ZpNlAAgvY0cFFBAc8Y7faf56nlwRFzGSoyCaI3jl4YWom8G9myJn1i3CW8byVw0d mF6OBgYGkNegMmhgxa4TLhTfcF.r3Y91gpovyxM__vrUW6i5WCf5x7.m5nJT45aElR2kX83DbwBi NmATHKCTFupJvTRt63Ov4T.llDZfKf6.RSQq..N_e0UjejkdXnwECdYD_D3SqjF8FvnAziF63._i iVrgupdtN2XHIhA7MrctHohfUnqyOkQGi9jL.GEuHqsI__5Pk99lsKBw1wTydT7aDRfWvnzQ66jR BeXWjW4i.zmrNom.fw99P9HgfhaJwSX38yOvJoX5hIFr5MxWqx4n2BSR6hzCUrqy2GPv1rg7sscF 04wPj5LLmz1M31L3cdJ4tP9DaTtRk5L6EscUYDBJtTJKEUtvCeq.WX.wlOOjfTDpNzzv_PSSVnr6 ARBTwIqNupbJ3ttV1u.Kmg90TQf5wvletpej78WzQMsPq0OokJmU- X-Sonic-MF: X-Sonic-ID: d9890575-f149-4b5e-be48-4135adf15a79 Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.bf2.yahoo.com with HTTP; Wed, 6 Aug 2025 23:50:33 +0000 Received: by hermes--production-bf1-689c4795f-7hfxj (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 2eb008ff4e51ab234597c6db9eca766d; Wed, 06 Aug 2025 23:50:29 +0000 (UTC) Received: by mail-oa1-f42.google.com with SMTP id 586e51a60fabf-30b8c77361eso121761fac.0 for ; Wed, 06 Aug 2025 16:50:29 -0700 (PDT) X-Gm-Message-State: AOJu0YzYewqH1wjgkK7K6bMfEZkq2LSZ3KA8Nsvwbtj+29LnXfPfmt8C RUpGbf0HToF1LmxagKwQFQKXHcegbSYgJCt7QST6o463iWcJyxipT0CGSQViLLCx1iR/WKGZJAG jH2HOvrfMoiS9+pVnLouaekGKncD74+A= X-Received: by 2002:a05:6870:c0d5:b0:307:bfe5:481e with SMTP id 586e51a60fabf-30be2c6ac28mr3399085fac.27.1754524228658; Wed, 06 Aug 2025 16:50:28 -0700 (PDT) MIME-Version: 1.0 Date: Wed, 6 Aug 2025 19:50:16 -0400 X-Gmail-Original-Message-ID: X-Gm-Features: Ac12FXw1OkTDpzBpQgLMCzXpecidPsV9k8Gang2bU5Dju2mqKp9zZzFd2zj0Ybk 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: 60809 X-Spam-Score: 4.2 (++++) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-2.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: I was still working on looking into some potential limited access to gerrit. I manually ported the diff from the 2.6 source code I was able to compile and run with over to the generalized master branc [...] Content analysis details: (4.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [74.6.128.33 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: 1ujnu8-00010n-Fo Subject: [Openvpn-devel] Bulk mode - Feature request - Patch diff 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?1839752026000190157?= X-GMAIL-MSGID: =?utf-8?q?1839752026000190157?= I was still working on looking into some potential limited access to gerrit. I manually ported the diff from the 2.6 source code I was able to compile and run with over to the generalized master branch which doesn't contain any configure/makefile so I am not able to build/run that version at the moment (untested). I made some changes to try and optimize some parts and cover more edge cases and I also put in a command line option to use this feature otherwise it should not affect the rest of the code base if the option is omitted. In the meantime I created an initial example pull request to gauge if anyone is actually interested in this work and/or if anyone has any general initial thoughts or feedback on code quality as I am actually using this right now personally. In the case that anyone is interested in such a change I will paste the generated patch diff below otherwise I will continue to run this experimental build at home here and see what happens! :) Thanks, Jon C https://github.com/OpenVPN/openvpn/pull/814/files $ cat 0001-bulk-mode.patch From 1b15b4aed623e7490d72ed7e21c3873a05630dd1 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 | 226 ++++++++++++++++++++++++++++++++++++++++-- src/openvpn/forward.h | 4 + src/openvpn/init.c | 46 +++++++++ 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, 315 insertions(+), 12 deletions(-) -- 2.39.5 (Apple Git-154) diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 75ca9d5c..37249802 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,28 @@ 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.len = 0; + uint8_t *temp = BPTR(&c->c2.to_tun); + if ((temp[0] == 0xff) && (temp[1] == 0x13) && (temp[2] == 0x37) && (temp[3] == 0xff)) + { + 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 += 6; + c->c2.buf.offset += 6; + } + } +} + static void process_incoming_link(struct context *c, struct link_socket *sock) { @@ -1221,6 +1288,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 +1389,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 +1450,54 @@ 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; + while ((c->c2.buffers->bufs_indx + 1) < TUN_BAT_MIN) + { + int leng = plen; + int indx = (c->c2.buffers->bufs_indx + 1); + 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 +1585,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 +1604,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 +1628,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 +1640,65 @@ 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) + { + if (maxl < 1) + { + temp[0] = 0xff; temp[1] = 0x13; temp[2] = 0x37; temp[3] = 0xff; + temp += 4; maxl += 4; + } + 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 +1925,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 +1970,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 +2070,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 +2090,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 +2103,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 +2160,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); + temp += 4; maxl += 4; + 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; } + } + } +} + +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..47818bbb 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); 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