[pve-devel] [PATCH http-server 1/4] websocket: improve masking performance

Fabian Grünbichler f.gruenbichler at proxmox.com
Fri Mar 6 11:20:27 CET 2020


in order to make websocket proxying feasible as general tunnel, we need
to be able to transfer more than a few MB/s

Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
 PVE/APIServer/AnyEvent.pm | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/PVE/APIServer/AnyEvent.pm b/PVE/APIServer/AnyEvent.pm
index 3ce948f..9f432e1 100644
--- a/PVE/APIServer/AnyEvent.pm
+++ b/PVE/APIServer/AnyEvent.pm
@@ -479,19 +479,19 @@ sub websocket_proxy {
 
 		    my $data = substr($hdl->{rbuf}, 0, $offset + 4 + $payload_len, ''); # now consume data
 
-		    my @mask = (unpack('C', substr($data, $offset+0, 1)),
-			unpack('C', substr($data, $offset+1, 1)),
-			unpack('C', substr($data, $offset+2, 1)),
-			unpack('C', substr($data, $offset+3, 1)));
-
+		    my $mask = substr($data, $offset, 4);
 		    $offset += 4;
 
 		    my $payload = substr($data, $offset, $payload_len);
 
-		    for (my $i = 0; $i < $payload_len; $i++) {
-			my $d = unpack('C', substr($payload, $i, 1));
-			my $n = $d ^ $mask[$i % 4];
-			substr($payload, $i, 1, pack('C', $n));
+		    # NULL-mask might be used over TLS, skip to increase performance
+		    if ($mask ne pack('N', 0)) {
+			# repeat 4 byte mask to payload length + up to 4 byte
+			$mask = $mask x (int($payload_len / 4) + 1);
+			# truncate mask to payload length
+			substr($mask, $payload_len) = "";
+			# (un-)apply mask
+			$payload ^= $mask;
 		    }
 
 		    $payload = decode_base64($payload) if !$binary;
-- 
2.20.1





More information about the pve-devel mailing list