From 61eb662e5fd8fcc26afb4f6eda179e09f9c6388d Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Mon, 2 Sep 2019 10:13:40 -0700 Subject: [PATCH] Ping and Pong messages cannot be fragmented (autobahn test: 5.1 and 5.2 Fragmentation) --- docs/CHANGELOG.md | 4 ++++ ixwebsocket/IXWebSocketCloseConstants.cpp | 2 ++ ixwebsocket/IXWebSocketCloseConstants.h | 2 ++ ixwebsocket/IXWebSocketTransport.cpp | 22 ++++++++++++++++++---- ixwebsocket/IXWebSocketVersion.h | 2 +- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 74c3dd5f..cede63f8 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to this project will be documented in this file. +## [5.1.2] - 2019-09-02 + +Ping and Pong messages cannot be fragmented (autobahn test: 5.1 and 5.2 Fragmentation) + ## [5.1.1] - 2019-09-01 Close connections when reserved bits are used (autobahn test: 3 Reserved Bits) diff --git a/ixwebsocket/IXWebSocketCloseConstants.cpp b/ixwebsocket/IXWebSocketCloseConstants.cpp index 81df5cfd..ff80bea6 100644 --- a/ixwebsocket/IXWebSocketCloseConstants.cpp +++ b/ixwebsocket/IXWebSocketCloseConstants.cpp @@ -21,4 +21,6 @@ namespace ix const std::string WebSocketCloseConstants::kProtocolErrorMessage("Protocol error"); const std::string WebSocketCloseConstants::kNoStatusCodeErrorMessage("No status code"); const std::string WebSocketCloseConstants::kProtocolErrorReservedBitUsed("Reserved bit used"); + const std::string WebSocketCloseConstants::kProtocolErrorPingPayloadOversized("Ping reason control frame with payload length > 125 octets"); + const std::string WebSocketCloseConstants::kProtocolErrorCodeControlMessageFragmented("Control message fragmented"); } diff --git a/ixwebsocket/IXWebSocketCloseConstants.h b/ixwebsocket/IXWebSocketCloseConstants.h index 74f16aa4..e45632fb 100644 --- a/ixwebsocket/IXWebSocketCloseConstants.h +++ b/ixwebsocket/IXWebSocketCloseConstants.h @@ -26,5 +26,7 @@ namespace ix static const std::string kProtocolErrorMessage; static const std::string kNoStatusCodeErrorMessage; static const std::string kProtocolErrorReservedBitUsed; + static const std::string kProtocolErrorPingPayloadOversized; + static const std::string kProtocolErrorCodeControlMessageFragmented; }; } // namespace ix diff --git a/ixwebsocket/IXWebSocketTransport.cpp b/ixwebsocket/IXWebSocketTransport.cpp index 0148ea24..8280a401 100644 --- a/ixwebsocket/IXWebSocketTransport.cpp +++ b/ixwebsocket/IXWebSocketTransport.cpp @@ -546,6 +546,17 @@ namespace ix return; /* Need: ws.header_size+ws.N - _rxbuf.size() */ } + if (!ws.fin && ( + ws.opcode == wsheader_type::PING + || ws.opcode == wsheader_type::PONG + || ws.opcode == wsheader_type::CLOSE + )){ + // Cntrol messages should not be fragmented + close(WebSocketCloseConstants::kProtocolErrorCode, + WebSocketCloseConstants::kProtocolErrorCodeControlMessageFragmented); + return; + } + // We got a whole message, now do something with it: if ( ws.opcode == wsheader_type::TEXT_FRAME @@ -603,11 +614,9 @@ namespace ix // too large if (pingData.size() > 125) { - std::string reason("reason control frame with payload length > 125 octets"); // Unexpected frame type - close(1002, - reason, - reason.size()); + close(WebSocketCloseConstants::kProtocolErrorCode, + WebSocketCloseConstants::kProtocolErrorPingPayloadOversized); return; } @@ -1070,6 +1079,11 @@ namespace ix if (_readyState == ReadyState::CLOSING || _readyState == ReadyState::CLOSED) return; + if (closeWireSize == 0) + { + closeWireSize = reason.size(); + } + { std::lock_guard lock(_closeDataMutex); _closeCode = code; diff --git a/ixwebsocket/IXWebSocketVersion.h b/ixwebsocket/IXWebSocketVersion.h index f7be8980..5009574c 100644 --- a/ixwebsocket/IXWebSocketVersion.h +++ b/ixwebsocket/IXWebSocketVersion.h @@ -6,4 +6,4 @@ #pragma once -#define IX_WEBSOCKET_VERSION "5.1.1" +#define IX_WEBSOCKET_VERSION "5.1.2"