From 72ab5d268e09b4fd776a6b111b5841bf2e2896e6 Mon Sep 17 00:00:00 2001 From: gubaojian Date: Mon, 23 Jun 2025 10:33:23 +0800 Subject: [PATCH 1/3] =?UTF-8?q?use=20precise=20mask=EF=BC=8C=20which=20is?= =?UTF-8?q?=20better=20than=20unprecise=20to=20avoid=20effect=20remain=20d?= =?UTF-8?q?ata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/WebSocketProtocol.h | 69 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/src/WebSocketProtocol.h b/src/WebSocketProtocol.h index 15d57a91c..3004c6c5a 100644 --- a/src/WebSocketProtocol.h +++ b/src/WebSocketProtocol.h @@ -295,6 +295,24 @@ struct WebSocketProtocol { } } + static inline void unmaskPrecise8(char *src, uint64_t maskInt, char* mask, unsigned int length) { + size_t lengthu64 = length/8; + uint64_t* u64I = (uint64_t*)src; + uint64_t* u64O = (uint64_t*)src; + for(size_t m=0; m 0) { + size_t roffset = length - remain; + char* rI = (src + roffset); + char* rO = (src + roffset); + for (size_t i=0; i static inline void unmaskImprecise4(char *src, uint32_t mask, unsigned int length) { @@ -322,6 +340,51 @@ struct WebSocketProtocol { } } + template + static inline void unmaskPreciseCopyMask(char *src, unsigned int length) { + if constexpr (HEADER_SIZE != 6) { + char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]}; + uint64_t maskInt; + memcpy(&maskInt, mask, 8); + + size_t lengthu64 = length/8; + uint64_t* u64I = (uint64_t*)src; + uint64_t* u64O = (uint64_t*)src; + for(size_t m=0; m 0) { + size_t roffset = length - remain; + char* rI = (src + roffset); + char* rO = (src + roffset); + for (size_t i=0; i 0) { + size_t roffset = length - remain; + char* rI = (src + roffset); + char* rO = (src + roffset); + for (size_t i=0; i(src + MESSAGE_HEADER, (unsigned int) payLength); - if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) { + /* use precise mask, which is better than unprecise to avoid effect remain data */ + unmaskPreciseCopyMask(src + MESSAGE_HEADER, (unsigned int) payLength); + if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) { return true; } } else { From 4caa84ea3402ea31412de3b4ce35d63eefcafd93 Mon Sep 17 00:00:00 2001 From: gubaojian Date: Mon, 23 Jun 2025 10:36:28 +0800 Subject: [PATCH 2/3] remove Chinese dot with english dot --- src/WebSocketProtocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketProtocol.h b/src/WebSocketProtocol.h index 3004c6c5a..fa3024a13 100644 --- a/src/WebSocketProtocol.h +++ b/src/WebSocketProtocol.h @@ -424,7 +424,7 @@ struct WebSocketProtocol { if (payLength + MESSAGE_HEADER <= length) { bool fin = isFin(src); if (isServer) { - /* use precise mask, which is better than unprecise to avoid effect remain data */ + /* use precise mask, which is better than unprecise to avoid effect remain data */ unmaskPreciseCopyMask(src + MESSAGE_HEADER, (unsigned int) payLength); if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) { return true; From 010d52c1bbce513b749950e11a173e16eca5f6fc Mon Sep 17 00:00:00 2001 From: gubaojian Date: Mon, 23 Jun 2025 12:21:53 +0800 Subject: [PATCH 3/3] fix continus message bug with presise mask --- src/WebSocketProtocol.h | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/WebSocketProtocol.h b/src/WebSocketProtocol.h index fa3024a13..280d267e2 100644 --- a/src/WebSocketProtocol.h +++ b/src/WebSocketProtocol.h @@ -402,6 +402,28 @@ struct WebSocketProtocol { } } + static inline void unmaskPreciseInplace(char *src, size_t length, char *mask) { + uint64_t maskInt; + memcpy(&maskInt, mask, 4); + memcpy(((char *)&maskInt) + 4, mask, 4); + + size_t lengthu64 = length/8; + uint64_t* u64I = (uint64_t*)src; + uint64_t* u64O = (uint64_t*)src; + for(size_t m=0; m 0) { + size_t roffset = length - remain; + char* rI = (src + roffset); + char* rO = (src + roffset); + for (size_t i=0; i static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState *wState, void *user) { if (getOpCode(src)) { @@ -450,10 +472,11 @@ struct WebSocketProtocol { bool fin = isFin(src); if constexpr (isServer) { memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4); - uint64_t mask; - memcpy(&mask, src + MESSAGE_HEADER - 4, 4); - memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4); - unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length); + uint64_t maskInt; + memcpy(&maskInt, src + MESSAGE_HEADER - 4, 4); + memcpy(((char *)&maskInt) + 4, src + MESSAGE_HEADER - 4, 4); + char* mask = src + MESSAGE_HEADER - 4; + unmaskPrecise8(src + MESSAGE_HEADER, maskInt, mask, length - MESSAGE_HEADER); rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask); } Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user); @@ -498,8 +521,7 @@ struct WebSocketProtocol { if /*constexpr*/ (LIBUS_RECV_BUFFER_LENGTH == length) { unmaskAll(src, wState->mask); } else { - // Slow path - unmaskInplace(src, src + ((length >> 2) + 1) * 4, wState->mask); + unmaskPreciseInplace(src, length, wState->mask); } } }