| 1418 | } |
| 1419 | |
| 1420 | std::optional<std::string> V2Transport::GetMessageType(std::span<const uint8_t>& contents) noexcept |
| 1421 | { |
| 1422 | if (contents.size() == 0) return std::nullopt; // Empty contents |
| 1423 | uint8_t first_byte = contents[0]; |
| 1424 | contents = contents.subspan(1); // Strip first byte. |
| 1425 | |
| 1426 | if (first_byte != 0) { |
| 1427 | // Short (1 byte) encoding. |
| 1428 | if (first_byte < std::size(V2_MESSAGE_IDS)) { |
| 1429 | // Valid short message id. |
| 1430 | return V2_MESSAGE_IDS[first_byte]; |
| 1431 | } else { |
| 1432 | // Unknown short message id. |
| 1433 | return std::nullopt; |
| 1434 | } |
| 1435 | } |
| 1436 | |
| 1437 | if (contents.size() < CMessageHeader::MESSAGE_TYPE_SIZE) { |
| 1438 | return std::nullopt; // Long encoding needs 12 message type bytes. |
| 1439 | } |
| 1440 | |
| 1441 | size_t msg_type_len{0}; |
| 1442 | while (msg_type_len < CMessageHeader::MESSAGE_TYPE_SIZE && contents[msg_type_len] != 0) { |
| 1443 | // Verify that message type bytes before the first 0x00 are in range. |
| 1444 | if (contents[msg_type_len] < ' ' || contents[msg_type_len] > 0x7F) { |
| 1445 | return {}; |
| 1446 | } |
| 1447 | ++msg_type_len; |
| 1448 | } |
| 1449 | std::string ret{reinterpret_cast<const char*>(contents.data()), msg_type_len}; |
| 1450 | while (msg_type_len < CMessageHeader::MESSAGE_TYPE_SIZE) { |
| 1451 | // Verify that message type bytes after the first 0x00 are also 0x00. |
| 1452 | if (contents[msg_type_len] != 0) return {}; |
| 1453 | ++msg_type_len; |
| 1454 | } |
| 1455 | // Strip message type bytes of contents. |
| 1456 | contents = contents.subspan(CMessageHeader::MESSAGE_TYPE_SIZE); |
| 1457 | return ret; |
| 1458 | } |
| 1459 | |
| 1460 | CNetMessage V2Transport::GetReceivedMessage(NodeClock::time_point time, bool& reject_message) noexcept |
| 1461 | { |