stun_tcp_packet_processor.cc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/protocol/stun_tcp_packet_processor.h"
  5. #include "base/no_destructor.h"
  6. #include "base/notreached.h"
  7. #include "base/sys_byteorder.h"
  8. #include "net/base/io_buffer.h"
  9. #include "third_party/webrtc/media/base/rtp_utils.h"
  10. #include "third_party/webrtc/rtc_base/time_utils.h"
  11. namespace remoting {
  12. namespace protocol {
  13. namespace {
  14. using PacketLength = uint16_t;
  15. constexpr size_t kPacketHeaderSize = sizeof(PacketLength);
  16. constexpr size_t kStunHeaderSize = 20;
  17. constexpr size_t kTurnChannelDataHeaderSize = 4;
  18. constexpr size_t kPacketLengthOffset = 2;
  19. int GetExpectedStunPacketSize(const uint8_t* data,
  20. size_t len,
  21. size_t* pad_bytes) {
  22. DCHECK_LE(kTurnChannelDataHeaderSize, len);
  23. // Both stun and turn had length at offset 2.
  24. size_t packet_size = base::NetToHost16(
  25. *reinterpret_cast<const uint16_t*>(data + kPacketLengthOffset));
  26. // Get packet type (STUN or TURN).
  27. uint16_t msg_type =
  28. base::NetToHost16(*reinterpret_cast<const uint16_t*>(data));
  29. *pad_bytes = 0;
  30. // Add header length to packet length.
  31. if ((msg_type & 0xC000) == 0) {
  32. packet_size += kStunHeaderSize;
  33. } else {
  34. packet_size += kTurnChannelDataHeaderSize;
  35. // Calculate any padding if present.
  36. if (packet_size % 4)
  37. *pad_bytes = 4 - packet_size % 4;
  38. }
  39. return packet_size;
  40. }
  41. } // namespace
  42. StunTcpPacketProcessor::StunTcpPacketProcessor() = default;
  43. StunTcpPacketProcessor::~StunTcpPacketProcessor() = default;
  44. // static
  45. StunTcpPacketProcessor* StunTcpPacketProcessor::GetInstance() {
  46. static base::NoDestructor<StunTcpPacketProcessor> instance;
  47. return instance.get();
  48. }
  49. scoped_refptr<net::IOBufferWithSize> StunTcpPacketProcessor::Pack(
  50. const uint8_t* data,
  51. size_t data_size) const {
  52. // Each packet is expected to have header (STUN/TURN ChannelData), where
  53. // header contains message type and and length of message.
  54. if (data_size < kPacketHeaderSize + kPacketLengthOffset) {
  55. NOTREACHED();
  56. return nullptr;
  57. }
  58. size_t pad_bytes;
  59. size_t expected_len = GetExpectedStunPacketSize(data, data_size, &pad_bytes);
  60. // Accepts only complete STUN/TURN packets.
  61. if (data_size != expected_len) {
  62. NOTREACHED();
  63. return nullptr;
  64. }
  65. // Add any pad bytes to the total size.
  66. size_t size = data_size + pad_bytes;
  67. auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(size);
  68. memcpy(buffer->data(), data, data_size);
  69. if (pad_bytes) {
  70. char padding[4] = {0};
  71. DCHECK_LE(pad_bytes, 4u);
  72. memcpy(buffer->data() + data_size, padding, pad_bytes);
  73. }
  74. return buffer;
  75. }
  76. scoped_refptr<net::IOBufferWithSize> StunTcpPacketProcessor::Unpack(
  77. const uint8_t* data,
  78. size_t data_size,
  79. size_t* bytes_consumed) const {
  80. *bytes_consumed = 0;
  81. if (data_size < kPacketHeaderSize + kPacketLengthOffset)
  82. return nullptr;
  83. size_t pad_bytes;
  84. size_t packet_size = GetExpectedStunPacketSize(data, data_size, &pad_bytes);
  85. if (data_size < packet_size + pad_bytes)
  86. return nullptr;
  87. // We have a complete packet.
  88. const uint8_t* cur = data;
  89. *bytes_consumed = packet_size + pad_bytes;
  90. auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(packet_size);
  91. memcpy(buffer->data(), cur, packet_size);
  92. return buffer;
  93. }
  94. void StunTcpPacketProcessor::ApplyPacketOptions(
  95. uint8_t* data,
  96. size_t data_size,
  97. const rtc::PacketTimeUpdateParams& packet_time_params) const {
  98. cricket::ApplyPacketOptions(data, data_size, packet_time_params,
  99. rtc::TimeMicros());
  100. }
  101. } // namespace protocol
  102. } // namespace remoting