1 // Copyright (c) 2014 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.
5 #include "content/browser/renderer_host/p2p/socket_host.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
11 #include "net/base/ip_endpoint.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 static unsigned char kFakeTag
[4] = { 0xba, 0xdd, 0xba, 0xdd };
16 static unsigned char kTestKey
[] = "12345678901234567890";
17 static unsigned char kTestAstValue
[3] = { 0xaa, 0xbb, 0xcc };
19 // Rtp message with invalid length.
20 static unsigned char kRtpMsgWithInvalidLength
[] = {
21 0x94, 0x00, 0x00, 0x00,
22 0x00, 0x00, 0x00, 0x00,
23 0xAA, 0xBB, 0xCC, 0XDD, // SSRC
24 0xDD, 0xCC, 0xBB, 0xAA // Only 1 CSRC, but CC count is 4.
27 // Rtp message with single byte header extension, invalid extension length.
28 static unsigned char kRtpMsgWithInvalidExtnLength
[] = {
29 0x90, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00,
32 0xBE, 0xDE, 0x0A, 0x00 // Extn length - 0x0A00
35 // Valid rtp Message with 2 byte header extension.
36 static unsigned char kRtpMsgWith2ByteExtnHeader
[] = {
37 0x90, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00,
39 0xAA, 0xBB, 0xCC, 0XDD, // SSRC
40 0x10, 0x00, 0x00, 0x01, // 2 Byte header extension
41 0x01, 0x00, 0x00, 0x00
44 // Stun Indication message with Zero length
45 static unsigned char kTurnSendIndicationMsgWithNoAttributes
[] = {
46 0x00, 0x16, 0x00, 0x00, // Zero length
47 0x21, 0x12, 0xA4, 0x42, // magic cookie
48 '0', '1', '2', '3', // transaction id
53 // Stun Send Indication message with invalid length in stun header.
54 static unsigned char kTurnSendIndicationMsgWithInvalidLength
[] = {
55 0x00, 0x16, 0xFF, 0x00, // length of 0xFF00
56 0x21, 0x12, 0xA4, 0x42, // magic cookie
57 '0', '1', '2', '3', // transaction id
62 // Stun Send Indication message with no DATA attribute in message.
63 static unsigned char kTurnSendIndicatinMsgWithNoDataAttribute
[] = {
64 0x00, 0x16, 0x00, 0x08, // length of
65 0x21, 0x12, 0xA4, 0x42, // magic cookie
66 '0', '1', '2', '3', // transaction id
69 0x00, 0x20, 0x00, 0x04, // Mapped address.
70 0x00, 0x00, 0x00, 0x00
73 // A valid STUN indication message with a valid RTP header in data attribute
74 // payload field and no extension bit set.
75 static unsigned char kTurnSendIndicationMsgWithoutRtpExtension
[] = {
76 0x00, 0x16, 0x00, 0x18, // length of
77 0x21, 0x12, 0xA4, 0x42, // magic cookie
78 '0', '1', '2', '3', // transaction id
81 0x00, 0x20, 0x00, 0x04, // Mapped address.
82 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x13, 0x00, 0x0C, // Data attribute.
84 0x80, 0x00, 0x00, 0x00, // RTP packet.
85 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00,
89 // A valid STUN indication message with a valid RTP header and a extension
91 static unsigned char kTurnSendIndicationMsgWithAbsSendTimeExtension
[] = {
92 0x00, 0x16, 0x00, 0x24, // length of
93 0x21, 0x12, 0xA4, 0x42, // magic cookie
94 '0', '1', '2', '3', // transaction id
97 0x00, 0x20, 0x00, 0x04, // Mapped address.
98 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x13, 0x00, 0x18, // Data attribute.
100 0x90, 0x00, 0x00, 0x00, // RTP packet.
101 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00,
103 0xBE, 0xDE, 0x00, 0x02,
104 0x22, 0xaa, 0xbb, 0xcc,
105 0x32, 0xaa, 0xbb, 0xcc,
108 // A valid TURN channel header, but not RTP packet.
109 static unsigned char kTurnChannelMsgNoRtpPacket
[] = {
110 0x40, 0x00, 0x00, 0x04,
111 0xaa, 0xbb, 0xcc, 0xdd,
114 // Turn ChannelMessage with zero length of payload.
115 static unsigned char kTurnChannelMsgWithZeroLength
[] = {
116 0x40, 0x00, 0x00, 0x00
119 // Turn ChannelMessage, wrapping a RTP packet without extension.
120 static unsigned char kTurnChannelMsgWithRtpPacket
[] = {
121 0x40, 0x00, 0x00, 0x0C,
122 0x80, 0x00, 0x00, 0x00, // RTP packet.
123 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00,
127 // Turn ChannelMessage, wrapping a RTP packet with AbsSendTime Extension.
128 static unsigned char kTurnChannelMsgWithAbsSendTimeExtension
[] = {
129 0x40, 0x00, 0x00, 0x14,
130 0x90, 0x00, 0x00, 0x00, // RTP packet.
131 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00,
133 0xBE, 0xDE, 0x00, 0x01,
134 0x32, 0xaa, 0xbb, 0xcc,
137 // RTP packet with single byte extension header of length 4 bytes.
138 // Extension id = 3 and length = 3
139 static unsigned char kRtpMsgWithAbsSendTimeExtension
[] = {
140 0x90, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00,
143 0xBE, 0xDE, 0x00, 0x02,
144 0x22, 0x00, 0x02, 0x1c,
145 0x32, 0xaa, 0xbb, 0xcc,
148 // Index of AbsSendTimeExtn data in message |kRtpMsgWithAbsSendTimeExtension|.
149 static const int kAstIndexInRtpMsg
= 21;
153 // This test verifies parsing of all invalid raw packets.
154 TEST(P2PSocketHostTest
, TestInvalidRawRtpMessages
) {
155 size_t start_pos
= SIZE_MAX
, rtp_length
= SIZE_MAX
;
156 EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
157 reinterpret_cast<char*>(kRtpMsgWithInvalidLength
),
158 sizeof(kRtpMsgWithInvalidLength
),
159 &start_pos
, &rtp_length
));
160 EXPECT_EQ(SIZE_MAX
, start_pos
);
161 EXPECT_EQ(SIZE_MAX
, rtp_length
);
163 EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
164 reinterpret_cast<char*>(kRtpMsgWithInvalidExtnLength
),
165 sizeof(kRtpMsgWithInvalidExtnLength
),
166 &start_pos
, &rtp_length
));
167 EXPECT_EQ(SIZE_MAX
, start_pos
);
168 EXPECT_EQ(SIZE_MAX
, rtp_length
);
171 // Verify invalid TURN send indication messages. Messages are proper STUN
172 // messages with incorrect values in attributes.
173 TEST(P2PSocketHostTest
, TestInvalidTurnSendIndicationMessages
) {
174 // Initializing out params to very large value.
175 size_t start_pos
= SIZE_MAX
, rtp_length
= SIZE_MAX
;
176 EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
177 reinterpret_cast<char*>(kTurnSendIndicationMsgWithNoAttributes
),
178 sizeof(kTurnSendIndicationMsgWithNoAttributes
),
179 &start_pos
, &rtp_length
));
180 EXPECT_EQ(SIZE_MAX
, start_pos
);
181 EXPECT_EQ(SIZE_MAX
, rtp_length
);
183 EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
184 reinterpret_cast<char*>(kTurnSendIndicationMsgWithInvalidLength
),
185 sizeof(kTurnSendIndicationMsgWithInvalidLength
),
186 &start_pos
, &rtp_length
));
187 EXPECT_EQ(SIZE_MAX
, start_pos
);
188 EXPECT_EQ(SIZE_MAX
, rtp_length
);
190 EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
191 reinterpret_cast<char*>(kTurnSendIndicatinMsgWithNoDataAttribute
),
192 sizeof(kTurnSendIndicatinMsgWithNoDataAttribute
),
193 &start_pos
, &rtp_length
));
194 EXPECT_EQ(SIZE_MAX
, start_pos
);
195 EXPECT_EQ(SIZE_MAX
, rtp_length
);
198 // This test verifies incorrectly formed TURN channel messages.
199 TEST(P2PSocketHostTest
, TestInvalidTurnChannelMessages
) {
200 size_t start_pos
= SIZE_MAX
, rtp_length
= SIZE_MAX
;
201 EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
202 reinterpret_cast<char*>(kTurnChannelMsgNoRtpPacket
),
203 sizeof(kTurnChannelMsgNoRtpPacket
),
204 &start_pos
, &rtp_length
));
205 EXPECT_EQ(SIZE_MAX
, start_pos
);
206 EXPECT_EQ(SIZE_MAX
, rtp_length
);
208 EXPECT_FALSE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
209 reinterpret_cast<char*>(kTurnChannelMsgWithZeroLength
),
210 sizeof(kTurnChannelMsgWithZeroLength
),
211 &start_pos
, &rtp_length
));
212 EXPECT_EQ(SIZE_MAX
, start_pos
);
213 EXPECT_EQ(SIZE_MAX
, rtp_length
);
216 // This test verifies parsing of a valid RTP packet which has 2byte header
217 // extension instead of a 1 byte header extension.
218 TEST(P2PSocketHostTest
, TestValid2ByteExtnHdrRtpMessage
) {
219 size_t start_pos
= SIZE_MAX
, rtp_length
= SIZE_MAX
;
220 EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
221 reinterpret_cast<char*>(kRtpMsgWith2ByteExtnHeader
),
222 sizeof(kRtpMsgWith2ByteExtnHeader
),
223 &start_pos
, &rtp_length
));
224 EXPECT_EQ(20U, rtp_length
);
225 EXPECT_EQ(0U, start_pos
);
228 // This test verifies parsing of a valid RTP packet which has 1 byte header
229 // AbsSendTime extension in it.
230 TEST(P2PSocketHostTest
, TestValidRtpPacketWithAbsSendTimeExtension
) {
231 size_t start_pos
= SIZE_MAX
, rtp_length
= SIZE_MAX
;
232 EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
233 reinterpret_cast<char*>(kRtpMsgWithAbsSendTimeExtension
),
234 sizeof(kRtpMsgWithAbsSendTimeExtension
),
235 &start_pos
, &rtp_length
));
236 EXPECT_EQ(24U, rtp_length
);
237 EXPECT_EQ(0U, start_pos
);
240 // This test verifies parsing of a valid TURN Send Indication messages.
241 TEST(P2PSocketHostTest
, TestValidTurnSendIndicationMessages
) {
242 size_t start_pos
= SIZE_MAX
, rtp_length
= SIZE_MAX
;
243 EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
244 reinterpret_cast<char*>(kTurnSendIndicationMsgWithoutRtpExtension
),
245 sizeof(kTurnSendIndicationMsgWithoutRtpExtension
),
246 &start_pos
, &rtp_length
));
247 EXPECT_EQ(12U, rtp_length
);
248 EXPECT_EQ(32U, start_pos
);
250 start_pos
= SIZE_MAX
, rtp_length
= SIZE_MAX
;
251 EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
252 reinterpret_cast<char*>(kTurnSendIndicationMsgWithAbsSendTimeExtension
),
253 sizeof(kTurnSendIndicationMsgWithAbsSendTimeExtension
),
254 &start_pos
, &rtp_length
));
255 EXPECT_EQ(24U, rtp_length
);
256 EXPECT_EQ(32U, start_pos
);
259 // This test verifies parsing of valid TURN Channel Messages.
260 TEST(P2PSocketHostTest
, TestValidTurnChannelMessages
) {
261 size_t start_pos
= 0, rtp_length
= 0;
262 EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
263 reinterpret_cast<char*>(kTurnChannelMsgWithRtpPacket
),
264 sizeof(kTurnChannelMsgWithRtpPacket
), &start_pos
, &rtp_length
));
265 EXPECT_EQ(12U, rtp_length
);
266 EXPECT_EQ(4U, start_pos
);
268 start_pos
= 0, rtp_length
= 0;
269 EXPECT_TRUE(packet_processing_helpers::GetRtpPacketStartPositionAndLength(
270 reinterpret_cast<char*>(kTurnChannelMsgWithAbsSendTimeExtension
),
271 sizeof(kTurnChannelMsgWithAbsSendTimeExtension
),
272 &start_pos
, &rtp_length
));
273 EXPECT_EQ(20U, rtp_length
);
274 EXPECT_EQ(4U, start_pos
);
277 // Verify handling of a 2 byte extension header RTP messsage. Currently we don't
278 // handle this kind of message.
279 TEST(P2PSocketHostTest
, TestUpdateAbsSendTimeExtensionIn2ByteHeaderExtn
) {
280 EXPECT_FALSE(packet_processing_helpers::UpdateRtpAbsSendTimeExtension(
281 reinterpret_cast<char*>(kRtpMsgWith2ByteExtnHeader
),
282 sizeof(kRtpMsgWith2ByteExtnHeader
),
287 // Verify finding an extension ID in the TURN send indication message.
288 TEST(P2PSocketHostTest
, TestUpdateAbsSendTimeExtensionInTurnSendIndication
) {
289 EXPECT_TRUE(packet_processing_helpers::UpdateRtpAbsSendTimeExtension(
290 reinterpret_cast<char*>(kTurnSendIndicationMsgWithoutRtpExtension
),
291 sizeof(kTurnSendIndicationMsgWithoutRtpExtension
),
295 EXPECT_TRUE(packet_processing_helpers::UpdateRtpAbsSendTimeExtension(
296 reinterpret_cast<char*>(kTurnSendIndicationMsgWithAbsSendTimeExtension
),
297 sizeof(kTurnSendIndicationMsgWithAbsSendTimeExtension
),
302 // Test without any packet options variables set. This method should return
303 // without HMAC value in the packet.
304 TEST(P2PSocketHostTest
, TestApplyPacketOptionsWithDefaultValues
) {
305 unsigned char fake_tag
[4] = { 0xba, 0xdd, 0xba, 0xdd };
306 rtc::PacketOptions options
;
307 std::vector
<char> rtp_packet
;
308 rtp_packet
.resize(sizeof(kRtpMsgWithAbsSendTimeExtension
) + 4); // tag length
309 memcpy(&rtp_packet
[0], kRtpMsgWithAbsSendTimeExtension
,
310 sizeof(kRtpMsgWithAbsSendTimeExtension
));
311 memcpy(&rtp_packet
[sizeof(kRtpMsgWithAbsSendTimeExtension
)], fake_tag
, 4);
313 packet_processing_helpers::ApplyPacketOptions(
314 &rtp_packet
[0], rtp_packet
.size(), options
, 0));
315 // Making sure we have't updated the HMAC.
316 EXPECT_EQ(0, memcmp(&rtp_packet
[sizeof(kRtpMsgWithAbsSendTimeExtension
)],
319 // Verify AbsouluteSendTime extension field is not modified.
320 EXPECT_EQ(0, memcmp(&rtp_packet
[kAstIndexInRtpMsg
],
321 kTestAstValue
, sizeof(kTestAstValue
)));
324 // Veirfy HMAC is updated when packet option parameters are set.
325 TEST(P2PSocketHostTest
, TestApplyPacketOptionsWithAuthParams
) {
326 rtc::PacketOptions options
;
327 options
.packet_time_params
.srtp_auth_key
.resize(20);
328 options
.packet_time_params
.srtp_auth_key
.assign(
329 kTestKey
, kTestKey
+ sizeof(kTestKey
));
330 options
.packet_time_params
.srtp_auth_tag_len
= 4;
332 std::vector
<char> rtp_packet
;
333 rtp_packet
.resize(sizeof(kRtpMsgWithAbsSendTimeExtension
) + 4); // tag length
334 memcpy(&rtp_packet
[0], kRtpMsgWithAbsSendTimeExtension
,
335 sizeof(kRtpMsgWithAbsSendTimeExtension
));
336 memcpy(&rtp_packet
[sizeof(kRtpMsgWithAbsSendTimeExtension
)], kFakeTag
, 4);
337 EXPECT_TRUE(packet_processing_helpers::ApplyPacketOptions(
338 &rtp_packet
[0], rtp_packet
.size(), options
, 0));
339 // HMAC should be different from fake_tag.
340 EXPECT_NE(0, memcmp(&rtp_packet
[sizeof(kRtpMsgWithAbsSendTimeExtension
)],
341 kFakeTag
, sizeof(kFakeTag
)));
343 // Verify AbsouluteSendTime extension field is not modified.
344 EXPECT_EQ(0, memcmp(&rtp_packet
[kAstIndexInRtpMsg
],
345 kTestAstValue
, sizeof(kTestAstValue
)));
348 // Verify finding an extension ID in a raw rtp message.
349 TEST(P2PSocketHostTest
, TestUpdateAbsSendTimeExtensionInRtpPacket
) {
350 EXPECT_TRUE(packet_processing_helpers::UpdateRtpAbsSendTimeExtension(
351 reinterpret_cast<char*>(kRtpMsgWithAbsSendTimeExtension
),
352 sizeof(kRtpMsgWithAbsSendTimeExtension
),
357 // Verify we update both AbsSendTime extension header and HMAC.
358 TEST(P2PSocketHostTest
, TestApplyPacketOptionsWithAuthParamsAndAbsSendTime
) {
359 rtc::PacketOptions options
;
360 options
.packet_time_params
.srtp_auth_key
.resize(20);
361 options
.packet_time_params
.srtp_auth_key
.assign(
362 kTestKey
, kTestKey
+ sizeof(kTestKey
));
363 options
.packet_time_params
.srtp_auth_tag_len
= 4;
364 options
.packet_time_params
.rtp_sendtime_extension_id
= 3;
365 // 3 is also present in the test message.
367 std::vector
<char> rtp_packet
;
368 rtp_packet
.resize(sizeof(kRtpMsgWithAbsSendTimeExtension
) + 4); // tag length
369 memcpy(&rtp_packet
[0], kRtpMsgWithAbsSendTimeExtension
,
370 sizeof(kRtpMsgWithAbsSendTimeExtension
));
371 memcpy(&rtp_packet
[sizeof(kRtpMsgWithAbsSendTimeExtension
)], kFakeTag
, 4);
372 EXPECT_TRUE(packet_processing_helpers::ApplyPacketOptions(
373 &rtp_packet
[0], rtp_packet
.size(), options
, 0xccbbaa));
374 // HMAC should be different from fake_tag.
375 EXPECT_NE(0, memcmp(&rtp_packet
[sizeof(kRtpMsgWithAbsSendTimeExtension
)],
376 kFakeTag
, sizeof(kFakeTag
)));
378 // ApplyPackets should have the new timestamp passed as input.
379 unsigned char timestamp_array
[3] = { 0xcc, 0xbb, 0xaa };
380 EXPECT_EQ(0, memcmp(&rtp_packet
[kAstIndexInRtpMsg
],
381 timestamp_array
, sizeof(timestamp_array
)));
384 } // namespace content