From c55702c39b1fd3b44f96de33a78226db6f672923 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fabian=20Gr=C3=BCnbichler?= Date: Fri, 6 Mar 2020 11:20:27 +0100 Subject: [PATCH] websocket: improve masking performance MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- 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 654f8f9..534027d 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.39.2