Optimize unmasking of large messages
This commit is contained in:
+20
-1
@@ -273,6 +273,14 @@ protected:
|
|||||||
static inline bool rsv23(char *frame) {return *((unsigned char *) frame) & 48;}
|
static inline bool rsv23(char *frame) {return *((unsigned char *) frame) & 48;}
|
||||||
static inline bool rsv1(char *frame) {return *((unsigned char *) frame) & 64;}
|
static inline bool rsv1(char *frame) {return *((unsigned char *) frame) & 64;}
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
static inline void UnrolledXor(char * __restrict data, char * __restrict mask) {
|
||||||
|
if constexpr (N != 1) {
|
||||||
|
UnrolledXor<N - 1>(data, mask);
|
||||||
|
}
|
||||||
|
data[N - 1] ^= mask[(N - 1) % 4];
|
||||||
|
}
|
||||||
|
|
||||||
static inline void unmaskImprecise(char *dst, char *src, char *mask, unsigned int length) {
|
static inline void unmaskImprecise(char *dst, char *src, char *mask, unsigned int length) {
|
||||||
for (unsigned int n = (length >> 2) + 1; n; n--) {
|
for (unsigned int n = (length >> 2) + 1; n; n--) {
|
||||||
*(dst++) = *(src++) ^ mask[0];
|
*(dst++) = *(src++) ^ mask[0];
|
||||||
@@ -360,6 +368,13 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This one is nicely vectorized on both ARM64 and X64 - especially with -mavx */
|
||||||
|
static inline void unmaskAll(char * __restrict data, char * __restrict mask) {
|
||||||
|
for (int i = 0; i < LIBUS_RECV_BUFFER_LENGTH; i += 16) {
|
||||||
|
UnrolledXor<16>(data + i, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool consumeContinuation(char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
|
static inline bool consumeContinuation(char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
|
||||||
if (wState->remainingBytes <= length) {
|
if (wState->remainingBytes <= length) {
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
@@ -384,7 +399,11 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
unmaskInplace(src, src + ((length >> 2) + 1) * 4, wState->mask);
|
/* No need to unmask if mask is 0 */
|
||||||
|
uint32_t nullmask = 0;
|
||||||
|
if (!memcmp(wState->mask, &nullmask, sizeof(uint32_t))) {
|
||||||
|
unmaskAll(src, wState->mask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wState->remainingBytes -= length;
|
wState->remainingBytes -= length;
|
||||||
|
|||||||
Reference in New Issue
Block a user