Add STUN_ATTR_GOOG_MISC_INFO
This patch adds the new STUN attribute that has been registered at iana,
https://www.iana.org/assignments/stun-parameters/stun-parameters.xhtml#stun-parameters-4
This is part of the effort to land https://webrtc-review.googlesource.com/c/src/+/85520.
I have merged that patch with upstream, and is now doing privacy review of it.
This attribute is hence not yet used.
BUG=webrtc:9446
Change-Id: Iaf177b0c28a6aa830a9422260b67436bb05ac756
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/160043
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29843}
diff --git a/api/transport/stun.cc b/api/transport/stun.cc
index 5e00b33..7fa3c90 100644
--- a/api/transport/stun.cc
+++ b/api/transport/stun.cc
@@ -161,6 +161,10 @@
return static_cast<const StunByteStringAttribute*>(GetAttribute(type));
}
+const StunUInt16ListAttribute* StunMessage::GetUInt16List(int type) const {
+ return static_cast<const StunUInt16ListAttribute*>(GetAttribute(type));
+}
+
const StunErrorCodeAttribute* StunMessage::GetErrorCode() const {
return static_cast<const StunErrorCodeAttribute*>(
GetAttribute(STUN_ATTR_ERROR_CODE));
@@ -343,8 +347,9 @@
}
bool StunMessage::Read(ByteBufferReader* buf) {
- if (!buf->ReadUInt16(&type_))
+ if (!buf->ReadUInt16(&type_)) {
return false;
+ }
if (type_ & 0x8000) {
// RTP and RTCP set the MSB of first byte, since first two bits are version,
@@ -352,16 +357,19 @@
return false;
}
- if (!buf->ReadUInt16(&length_))
+ if (!buf->ReadUInt16(&length_)) {
return false;
+ }
std::string magic_cookie;
- if (!buf->ReadString(&magic_cookie, kStunMagicCookieLength))
+ if (!buf->ReadString(&magic_cookie, kStunMagicCookieLength)) {
return false;
+ }
std::string transaction_id;
- if (!buf->ReadString(&transaction_id, kStunTransactionIdLength))
+ if (!buf->ReadString(&transaction_id, kStunTransactionIdLength)) {
return false;
+ }
uint32_t magic_cookie_int;
static_assert(sizeof(magic_cookie_int) == kStunMagicCookieLength,
@@ -376,8 +384,9 @@
transaction_id_ = transaction_id;
reduced_transaction_id_ = ReduceTransactionId(transaction_id_);
- if (length_ != buf->Length())
+ if (length_ != buf->Length()) {
return false;
+ }
attrs_.resize(0);
@@ -396,11 +405,13 @@
if ((attr_length % 4) != 0) {
attr_length += (4 - (attr_length % 4));
}
- if (!buf->Consume(attr_length))
+ if (!buf->Consume(attr_length)) {
return false;
+ }
} else {
- if (!attr->Read(buf))
+ if (!attr->Read(buf)) {
return false;
+ }
attrs_.push_back(std::move(attr));
}
}
@@ -465,6 +476,8 @@
return STUN_VALUE_UINT32;
case STUN_ATTR_LAST_ICE_CHECK_RECEIVED:
return STUN_VALUE_BYTE_STRING;
+ case STUN_ATTR_GOOG_MISC_INFO:
+ return STUN_VALUE_UINT16_LIST;
default:
return STUN_VALUE_UNKNOWN;
}
@@ -573,6 +586,11 @@
}
std::unique_ptr<StunUInt16ListAttribute>
+StunAttribute::CreateUInt16ListAttribute(uint16_t type) {
+ return std::make_unique<StunUInt16ListAttribute>(type, 0);
+}
+
+std::unique_ptr<StunUInt16ListAttribute>
StunAttribute::CreateUnknownAttributes() {
return std::make_unique<StunUInt16ListAttribute>(STUN_ATTR_UNKNOWN_ATTRIBUTES,
0);
@@ -956,8 +974,9 @@
}
bool StunUInt16ListAttribute::Read(ByteBufferReader* buf) {
- if (length() % 2)
+ if (length() % 2) {
return false;
+ }
for (size_t i = 0; i < length() / 2; i++) {
uint16_t attr;
diff --git a/api/transport/stun.h b/api/transport/stun.h
index e19f196..02b352c 100644
--- a/api/transport/stun.h
+++ b/api/transport/stun.h
@@ -159,6 +159,7 @@
const StunUInt32Attribute* GetUInt32(int type) const;
const StunUInt64Attribute* GetUInt64(int type) const;
const StunByteStringAttribute* GetByteString(int type) const;
+ const StunUInt16ListAttribute* GetUInt16List(int type) const;
// Gets these specific attribute values.
const StunErrorCodeAttribute* GetErrorCode() const;
@@ -257,6 +258,8 @@
static std::unique_ptr<StunUInt64Attribute> CreateUInt64(uint16_t type);
static std::unique_ptr<StunByteStringAttribute> CreateByteString(
uint16_t type);
+ static std::unique_ptr<StunUInt16ListAttribute> CreateUInt16ListAttribute(
+ uint16_t type);
static std::unique_ptr<StunErrorCodeAttribute> CreateErrorCode();
static std::unique_ptr<StunUInt16ListAttribute> CreateUnknownAttributes();
@@ -615,8 +618,18 @@
STUN_ATTR_NETWORK_INFO = 0xC057,
// Experimental: Transaction ID of the last connectivity check received.
STUN_ATTR_LAST_ICE_CHECK_RECEIVED = 0xC058,
+ // Uint16List. Miscellaneous attributes for future extension.
+ STUN_ATTR_GOOG_MISC_INFO = 0xC059,
};
+// When adding new attributes to STUN_ATTR_GOOG_MISC_INFO
+// (which is a list of uint16_t), append the indices of these attributes below
+// and do NOT change the exisiting indices. The indices of attributes must be
+// consistent with those used in ConnectionRequest::Prepare when forming a STUN
+// message for the ICE connectivity check, and they are used when parsing a
+// received STUN message.
+enum class IceGoogMiscInfoAttributeIndex {};
+
// RFC 5245-defined errors.
enum IceErrorCode {
STUN_ERROR_ROLE_CONFLICT = 487,
diff --git a/api/transport/stun_unittest.cc b/api/transport/stun_unittest.cc
index 667746e..4baca59 100644
--- a/api/transport/stun_unittest.cc
+++ b/api/transport/stun_unittest.cc
@@ -1571,4 +1571,37 @@
EXPECT_EQ(reduced_transaction_id, 1835954016u);
}
+TEST_F(StunTest, GoogMiscInfo) {
+ StunMessage msg;
+ const size_t size =
+ /* msg header */ 20 +
+ /* attr header */ 4 +
+ /* 3 * 2 rounded to multiple of 4 */ 8;
+ msg.SetType(STUN_BINDING_REQUEST);
+ msg.SetTransactionID("ABCDEFGH");
+ auto list =
+ StunAttribute::CreateUInt16ListAttribute(STUN_ATTR_GOOG_MISC_INFO);
+ list->AddType(0x1U);
+ list->AddType(0x1000U);
+ list->AddType(0xAB0CU);
+ msg.AddAttribute(std::move(list));
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
+
+ rtc::ByteBufferWriter out;
+ EXPECT_TRUE(msg.Write(&out));
+ ASSERT_EQ(size, out.Length());
+
+ size_t read_size = ReadStunMessageTestCase(
+ &msg, reinterpret_cast<const unsigned char*>(out.Data()), out.Length());
+ ASSERT_EQ(read_size + 20, size);
+ CheckStunHeader(msg, STUN_BINDING_REQUEST, read_size);
+ const StunUInt16ListAttribute* types =
+ msg.GetUInt16List(STUN_ATTR_GOOG_MISC_INFO);
+ ASSERT_TRUE(types != NULL);
+ EXPECT_EQ(3U, types->Size());
+ EXPECT_EQ(0x1U, types->GetType(0));
+ EXPECT_EQ(0x1000U, types->GetType(1));
+ EXPECT_EQ(0xAB0CU, types->GetType(2));
+}
+
} // namespace cricket