Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / stun_unittest.cc
1 /*
2  * libjingle
3  * Copyright 2004 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include <string>
29
30 #include "talk/p2p/base/stun.h"
31 #include "webrtc/base/bytebuffer.h"
32 #include "webrtc/base/gunit.h"
33 #include "webrtc/base/logging.h"
34 #include "webrtc/base/messagedigest.h"
35 #include "webrtc/base/scoped_ptr.h"
36 #include "webrtc/base/socketaddress.h"
37
38 namespace cricket {
39
40 class StunTest : public ::testing::Test {
41  protected:
42   void CheckStunHeader(const StunMessage& msg, StunMessageType expected_type,
43                        size_t expected_length) {
44     ASSERT_EQ(expected_type, msg.type());
45     ASSERT_EQ(expected_length, msg.length());
46   }
47
48   void CheckStunTransactionID(const StunMessage& msg,
49                               const unsigned char* expectedID, size_t length) {
50     ASSERT_EQ(length, msg.transaction_id().size());
51     ASSERT_EQ(length == kStunTransactionIdLength + 4, msg.IsLegacy());
52     ASSERT_EQ(length == kStunTransactionIdLength, !msg.IsLegacy());
53     ASSERT_EQ(0, memcmp(msg.transaction_id().c_str(), expectedID, length));
54   }
55
56   void CheckStunAddressAttribute(const StunAddressAttribute* addr,
57                                  StunAddressFamily expected_family,
58                                  int expected_port,
59                                  rtc::IPAddress expected_address) {
60     ASSERT_EQ(expected_family, addr->family());
61     ASSERT_EQ(expected_port, addr->port());
62
63     if (addr->family() == STUN_ADDRESS_IPV4) {
64       in_addr v4_address = expected_address.ipv4_address();
65       in_addr stun_address = addr->ipaddr().ipv4_address();
66       ASSERT_EQ(0, memcmp(&v4_address, &stun_address, sizeof(stun_address)));
67     } else if (addr->family() == STUN_ADDRESS_IPV6) {
68       in6_addr v6_address = expected_address.ipv6_address();
69       in6_addr stun_address = addr->ipaddr().ipv6_address();
70       ASSERT_EQ(0, memcmp(&v6_address, &stun_address, sizeof(stun_address)));
71     } else {
72       ASSERT_TRUE(addr->family() == STUN_ADDRESS_IPV6 ||
73                   addr->family() == STUN_ADDRESS_IPV4);
74     }
75   }
76
77   size_t ReadStunMessageTestCase(StunMessage* msg,
78                                  const unsigned char* testcase,
79                                  size_t size) {
80     const char* input = reinterpret_cast<const char*>(testcase);
81     rtc::ByteBuffer buf(input, size);
82     if (msg->Read(&buf)) {
83       // Returns the size the stun message should report itself as being
84       return (size - 20);
85     } else {
86       return 0;
87     }
88   }
89 };
90
91
92 // Sample STUN packets with various attributes
93 // Gathered by wiresharking pjproject's pjnath test programs
94 // pjproject available at www.pjsip.org
95
96 static const unsigned char kStunMessageWithIPv6MappedAddress[] = {
97   0x00, 0x01, 0x00, 0x18,  // message header
98   0x21, 0x12, 0xa4, 0x42,  // transaction id
99   0x29, 0x1f, 0xcd, 0x7c,
100   0xba, 0x58, 0xab, 0xd7,
101   0xf2, 0x41, 0x01, 0x00,
102   0x00, 0x01, 0x00, 0x14,  // Address type (mapped), length
103   0x00, 0x02, 0xb8, 0x81,  // family (IPv6), port
104   0x24, 0x01, 0xfa, 0x00,  // an IPv6 address
105   0x00, 0x04, 0x10, 0x00,
106   0xbe, 0x30, 0x5b, 0xff,
107   0xfe, 0xe5, 0x00, 0xc3
108 };
109
110 static const unsigned char kStunMessageWithIPv4MappedAddress[] = {
111   0x01, 0x01, 0x00, 0x0c,   // binding response, length 12
112   0x21, 0x12, 0xa4, 0x42,   // magic cookie
113   0x29, 0x1f, 0xcd, 0x7c,   // transaction ID
114   0xba, 0x58, 0xab, 0xd7,
115   0xf2, 0x41, 0x01, 0x00,
116   0x00, 0x01, 0x00, 0x08,  // Mapped, 8 byte length
117   0x00, 0x01, 0x9d, 0xfc,  // AF_INET, unxor-ed port
118   0xac, 0x17, 0x44, 0xe6   // IPv4 address
119 };
120
121 // Test XOR-mapped IP addresses:
122 static const unsigned char kStunMessageWithIPv6XorMappedAddress[] = {
123   0x01, 0x01, 0x00, 0x18,  // message header (binding response)
124   0x21, 0x12, 0xa4, 0x42,  // magic cookie (rfc5389)
125   0xe3, 0xa9, 0x46, 0xe1,  // transaction ID
126   0x7c, 0x00, 0xc2, 0x62,
127   0x54, 0x08, 0x01, 0x00,
128   0x00, 0x20, 0x00, 0x14,  // Address Type (XOR), length
129   0x00, 0x02, 0xcb, 0x5b,  // family, XOR-ed port
130   0x05, 0x13, 0x5e, 0x42,  // XOR-ed IPv6 address
131   0xe3, 0xad, 0x56, 0xe1,
132   0xc2, 0x30, 0x99, 0x9d,
133   0xaa, 0xed, 0x01, 0xc3
134 };
135
136 static const unsigned char kStunMessageWithIPv4XorMappedAddress[] = {
137   0x01, 0x01, 0x00, 0x0c,  // message header (binding response)
138   0x21, 0x12, 0xa4, 0x42,  // magic cookie
139   0x29, 0x1f, 0xcd, 0x7c,  // transaction ID
140   0xba, 0x58, 0xab, 0xd7,
141   0xf2, 0x41, 0x01, 0x00,
142   0x00, 0x20, 0x00, 0x08,  // address type (xor), length
143   0x00, 0x01, 0xfc, 0xb5,  // family (AF_INET), XOR-ed port
144   0x8d, 0x05, 0xe0, 0xa4   // IPv4 address
145 };
146
147 // ByteString Attribute (username)
148 static const unsigned char kStunMessageWithByteStringAttribute[] = {
149   0x00, 0x01, 0x00, 0x0c,
150   0x21, 0x12, 0xa4, 0x42,
151   0xe3, 0xa9, 0x46, 0xe1,
152   0x7c, 0x00, 0xc2, 0x62,
153   0x54, 0x08, 0x01, 0x00,
154   0x00, 0x06, 0x00, 0x08,  // username attribute (length 8)
155   0x61, 0x62, 0x63, 0x64,  // abcdefgh
156   0x65, 0x66, 0x67, 0x68
157 };
158
159 // Message with an unknown but comprehensible optional attribute.
160 // Parsing should succeed despite this unknown attribute.
161 static const unsigned char kStunMessageWithUnknownAttribute[] = {
162   0x00, 0x01, 0x00, 0x14,
163   0x21, 0x12, 0xa4, 0x42,
164   0xe3, 0xa9, 0x46, 0xe1,
165   0x7c, 0x00, 0xc2, 0x62,
166   0x54, 0x08, 0x01, 0x00,
167   0x00, 0xaa, 0x00, 0x07,  // Unknown attribute, length 7 (needs padding!)
168   0x61, 0x62, 0x63, 0x64,  // abcdefg + padding
169   0x65, 0x66, 0x67, 0x00,
170   0x00, 0x06, 0x00, 0x03,  // Followed by a known attribute we can
171   0x61, 0x62, 0x63, 0x00   // check for (username of length 3)
172 };
173
174 // ByteString Attribute (username) with padding byte
175 static const unsigned char kStunMessageWithPaddedByteStringAttribute[] = {
176   0x00, 0x01, 0x00, 0x08,
177   0x21, 0x12, 0xa4, 0x42,
178   0xe3, 0xa9, 0x46, 0xe1,
179   0x7c, 0x00, 0xc2, 0x62,
180   0x54, 0x08, 0x01, 0x00,
181   0x00, 0x06, 0x00, 0x03,  // username attribute (length 3)
182   0x61, 0x62, 0x63, 0xcc   // abc
183 };
184
185 // Message with an Unknown Attributes (uint16 list) attribute.
186 static const unsigned char kStunMessageWithUInt16ListAttribute[] = {
187   0x00, 0x01, 0x00, 0x0c,
188   0x21, 0x12, 0xa4, 0x42,
189   0xe3, 0xa9, 0x46, 0xe1,
190   0x7c, 0x00, 0xc2, 0x62,
191   0x54, 0x08, 0x01, 0x00,
192   0x00, 0x0a, 0x00, 0x06,  // username attribute (length 6)
193   0x00, 0x01, 0x10, 0x00,  // three attributes plus padding
194   0xAB, 0xCU, 0xBE, 0xEF
195 };
196
197 // Error response message (unauthorized)
198 static const unsigned char kStunMessageWithErrorAttribute[] = {
199   0x01, 0x11, 0x00, 0x14,
200   0x21, 0x12, 0xa4, 0x42,
201   0x29, 0x1f, 0xcd, 0x7c,
202   0xba, 0x58, 0xab, 0xd7,
203   0xf2, 0x41, 0x01, 0x00,
204   0x00, 0x09, 0x00, 0x10,
205   0x00, 0x00, 0x04, 0x01,
206   0x55, 0x6e, 0x61, 0x75,
207   0x74, 0x68, 0x6f, 0x72,
208   0x69, 0x7a, 0x65, 0x64
209 };
210
211 // Sample messages with an invalid length Field
212
213 // The actual length in bytes of the invalid messages (including STUN header)
214 static const int kRealLengthOfInvalidLengthTestCases = 32;
215
216 static const unsigned char kStunMessageWithZeroLength[] = {
217   0x00, 0x01, 0x00, 0x00,  // length of 0 (last 2 bytes)
218   0x21, 0x12, 0xA4, 0x42,  // magic cookie
219   '0', '1', '2', '3',      // transaction id
220   '4', '5', '6', '7',
221   '8', '9', 'a', 'b',
222   0x00, 0x20, 0x00, 0x08,  // xor mapped address
223   0x00, 0x01, 0x21, 0x1F,
224   0x21, 0x12, 0xA4, 0x53,
225 };
226
227 static const unsigned char kStunMessageWithExcessLength[] = {
228   0x00, 0x01, 0x00, 0x55,  // length of 85
229   0x21, 0x12, 0xA4, 0x42,  // magic cookie
230   '0', '1', '2', '3',      // transaction id
231   '4', '5', '6', '7',
232   '8', '9', 'a', 'b',
233   0x00, 0x20, 0x00, 0x08,  // xor mapped address
234   0x00, 0x01, 0x21, 0x1F,
235   0x21, 0x12, 0xA4, 0x53,
236 };
237
238 static const unsigned char kStunMessageWithSmallLength[] = {
239   0x00, 0x01, 0x00, 0x03,  // length of 3
240   0x21, 0x12, 0xA4, 0x42,  // magic cookie
241   '0', '1', '2', '3',      // transaction id
242   '4', '5', '6', '7',
243   '8', '9', 'a', 'b',
244   0x00, 0x20, 0x00, 0x08,  // xor mapped address
245   0x00, 0x01, 0x21, 0x1F,
246   0x21, 0x12, 0xA4, 0x53,
247 };
248
249 // RTCP packet, for testing we correctly ignore non stun packet types.
250 // V=2, P=false, RC=0, Type=200, Len=6, Sender-SSRC=85, etc
251 static const unsigned char kRtcpPacket[] = {
252   0x80, 0xc8, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55,
253   0xce, 0xa5, 0x18, 0x3a, 0x39, 0xcc, 0x7d, 0x09,
254   0x23, 0xed, 0x19, 0x07, 0x00, 0x00, 0x01, 0x56,
255   0x00, 0x03, 0x73, 0x50,
256 };
257
258 // RFC5769 Test Vectors
259 // Software name (request):  "STUN test client" (without quotes)
260 // Software name (response): "test vector" (without quotes)
261 // Username:  "evtj:h6vY" (without quotes)
262 // Password:  "VOkJxbRl1RmTxUk/WvJxBt" (without quotes)
263 static const unsigned char kRfc5769SampleMsgTransactionId[] = {
264   0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae
265 };
266 static const char kRfc5769SampleMsgClientSoftware[] = "STUN test client";
267 static const char kRfc5769SampleMsgServerSoftware[] = "test vector";
268 static const char kRfc5769SampleMsgUsername[] = "evtj:h6vY";
269 static const char kRfc5769SampleMsgPassword[] = "VOkJxbRl1RmTxUk/WvJxBt";
270 static const rtc::SocketAddress kRfc5769SampleMsgMappedAddress(
271     "192.0.2.1", 32853);
272 static const rtc::SocketAddress kRfc5769SampleMsgIPv6MappedAddress(
273     "2001:db8:1234:5678:11:2233:4455:6677", 32853);
274
275 static const unsigned char kRfc5769SampleMsgWithAuthTransactionId[] = {
276   0x78, 0xad, 0x34, 0x33, 0xc6, 0xad, 0x72, 0xc0, 0x29, 0xda, 0x41, 0x2e
277 };
278 static const char kRfc5769SampleMsgWithAuthUsername[] =
279     "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9";
280 static const char kRfc5769SampleMsgWithAuthPassword[] = "TheMatrIX";
281 static const char kRfc5769SampleMsgWithAuthNonce[] =
282     "f//499k954d6OL34oL9FSTvy64sA";
283 static const char kRfc5769SampleMsgWithAuthRealm[] = "example.org";
284
285 // 2.1.  Sample Request
286 static const unsigned char kRfc5769SampleRequest[] = {
287   0x00, 0x01, 0x00, 0x58,   //    Request type and message length
288   0x21, 0x12, 0xa4, 0x42,   //    Magic cookie
289   0xb7, 0xe7, 0xa7, 0x01,   // }
290   0xbc, 0x34, 0xd6, 0x86,   // }  Transaction ID
291   0xfa, 0x87, 0xdf, 0xae,   // }
292   0x80, 0x22, 0x00, 0x10,   //    SOFTWARE attribute header
293   0x53, 0x54, 0x55, 0x4e,   // }
294   0x20, 0x74, 0x65, 0x73,   // }  User-agent...
295   0x74, 0x20, 0x63, 0x6c,   // }  ...name
296   0x69, 0x65, 0x6e, 0x74,   // }
297   0x00, 0x24, 0x00, 0x04,   //    PRIORITY attribute header
298   0x6e, 0x00, 0x01, 0xff,   //    ICE priority value
299   0x80, 0x29, 0x00, 0x08,   //    ICE-CONTROLLED attribute header
300   0x93, 0x2f, 0xf9, 0xb1,   // }  Pseudo-random tie breaker...
301   0x51, 0x26, 0x3b, 0x36,   // }   ...for ICE control
302   0x00, 0x06, 0x00, 0x09,   //    USERNAME attribute header
303   0x65, 0x76, 0x74, 0x6a,   // }
304   0x3a, 0x68, 0x36, 0x76,   // }  Username (9 bytes) and padding (3 bytes)
305   0x59, 0x20, 0x20, 0x20,   // }
306   0x00, 0x08, 0x00, 0x14,   //    MESSAGE-INTEGRITY attribute header
307   0x9a, 0xea, 0xa7, 0x0c,   // }
308   0xbf, 0xd8, 0xcb, 0x56,   // }
309   0x78, 0x1e, 0xf2, 0xb5,   // }  HMAC-SHA1 fingerprint
310   0xb2, 0xd3, 0xf2, 0x49,   // }
311   0xc1, 0xb5, 0x71, 0xa2,   // }
312   0x80, 0x28, 0x00, 0x04,   //    FINGERPRINT attribute header
313   0xe5, 0x7a, 0x3b, 0xcf    //    CRC32 fingerprint
314 };
315
316 // 2.2.  Sample IPv4 Response
317 static const unsigned char kRfc5769SampleResponse[] = {
318   0x01, 0x01, 0x00, 0x3c,  //     Response type and message length
319   0x21, 0x12, 0xa4, 0x42,  //     Magic cookie
320   0xb7, 0xe7, 0xa7, 0x01,  // }
321   0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
322   0xfa, 0x87, 0xdf, 0xae,  // }
323   0x80, 0x22, 0x00, 0x0b,  //    SOFTWARE attribute header
324   0x74, 0x65, 0x73, 0x74,  // }
325   0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
326   0x74, 0x6f, 0x72, 0x20,  // }
327   0x00, 0x20, 0x00, 0x08,  //    XOR-MAPPED-ADDRESS attribute header
328   0x00, 0x01, 0xa1, 0x47,  //    Address family (IPv4) and xor'd mapped port
329   0xe1, 0x12, 0xa6, 0x43,  //    Xor'd mapped IPv4 address
330   0x00, 0x08, 0x00, 0x14,  //    MESSAGE-INTEGRITY attribute header
331   0x2b, 0x91, 0xf5, 0x99,  // }
332   0xfd, 0x9e, 0x90, 0xc3,  // }
333   0x8c, 0x74, 0x89, 0xf9,  // }  HMAC-SHA1 fingerprint
334   0x2a, 0xf9, 0xba, 0x53,  // }
335   0xf0, 0x6b, 0xe7, 0xd7,  // }
336   0x80, 0x28, 0x00, 0x04,  //    FINGERPRINT attribute header
337   0xc0, 0x7d, 0x4c, 0x96   //    CRC32 fingerprint
338 };
339
340 // 2.3.  Sample IPv6 Response
341 static const unsigned char kRfc5769SampleResponseIPv6[] = {
342   0x01, 0x01, 0x00, 0x48,  //    Response type and message length
343   0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
344   0xb7, 0xe7, 0xa7, 0x01,  // }
345   0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
346   0xfa, 0x87, 0xdf, 0xae,  // }
347   0x80, 0x22, 0x00, 0x0b,  //    SOFTWARE attribute header
348   0x74, 0x65, 0x73, 0x74,  // }
349   0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
350   0x74, 0x6f, 0x72, 0x20,  // }
351   0x00, 0x20, 0x00, 0x14,  //    XOR-MAPPED-ADDRESS attribute header
352   0x00, 0x02, 0xa1, 0x47,  //    Address family (IPv6) and xor'd mapped port.
353   0x01, 0x13, 0xa9, 0xfa,  // }
354   0xa5, 0xd3, 0xf1, 0x79,  // }  Xor'd mapped IPv6 address
355   0xbc, 0x25, 0xf4, 0xb5,  // }
356   0xbe, 0xd2, 0xb9, 0xd9,  // }
357   0x00, 0x08, 0x00, 0x14,  //    MESSAGE-INTEGRITY attribute header
358   0xa3, 0x82, 0x95, 0x4e,  // }
359   0x4b, 0xe6, 0x7b, 0xf1,  // }
360   0x17, 0x84, 0xc9, 0x7c,  // }  HMAC-SHA1 fingerprint
361   0x82, 0x92, 0xc2, 0x75,  // }
362   0xbf, 0xe3, 0xed, 0x41,  // }
363   0x80, 0x28, 0x00, 0x04,  //    FINGERPRINT attribute header
364   0xc8, 0xfb, 0x0b, 0x4c   //    CRC32 fingerprint
365 };
366
367 // 2.4.  Sample Request with Long-Term Authentication
368 static const unsigned char kRfc5769SampleRequestLongTermAuth[] = {
369   0x00, 0x01, 0x00, 0x60,  //    Request type and message length
370   0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
371   0x78, 0xad, 0x34, 0x33,  // }
372   0xc6, 0xad, 0x72, 0xc0,  // }  Transaction ID
373   0x29, 0xda, 0x41, 0x2e,  // }
374   0x00, 0x06, 0x00, 0x12,  //    USERNAME attribute header
375   0xe3, 0x83, 0x9e, 0xe3,  // }
376   0x83, 0x88, 0xe3, 0x83,  // }
377   0xaa, 0xe3, 0x83, 0x83,  // }  Username value (18 bytes) and padding (2 bytes)
378   0xe3, 0x82, 0xaf, 0xe3,  // }
379   0x82, 0xb9, 0x00, 0x00,  // }
380   0x00, 0x15, 0x00, 0x1c,  //    NONCE attribute header
381   0x66, 0x2f, 0x2f, 0x34,  // }
382   0x39, 0x39, 0x6b, 0x39,  // }
383   0x35, 0x34, 0x64, 0x36,  // }
384   0x4f, 0x4c, 0x33, 0x34,  // }  Nonce value
385   0x6f, 0x4c, 0x39, 0x46,  // }
386   0x53, 0x54, 0x76, 0x79,  // }
387   0x36, 0x34, 0x73, 0x41,  // }
388   0x00, 0x14, 0x00, 0x0b,  //    REALM attribute header
389   0x65, 0x78, 0x61, 0x6d,  // }
390   0x70, 0x6c, 0x65, 0x2e,  // }  Realm value (11 bytes) and padding (1 byte)
391   0x6f, 0x72, 0x67, 0x00,  // }
392   0x00, 0x08, 0x00, 0x14,  //    MESSAGE-INTEGRITY attribute header
393   0xf6, 0x70, 0x24, 0x65,  // }
394   0x6d, 0xd6, 0x4a, 0x3e,  // }
395   0x02, 0xb8, 0xe0, 0x71,  // }  HMAC-SHA1 fingerprint
396   0x2e, 0x85, 0xc9, 0xa2,  // }
397   0x8c, 0xa8, 0x96, 0x66   // }
398 };
399
400 // Length parameter is changed to 0x38 from 0x58.
401 // AddMessageIntegrity will add MI information and update the length param
402 // accordingly.
403 static const unsigned char kRfc5769SampleRequestWithoutMI[] = {
404   0x00, 0x01, 0x00, 0x38,  //    Request type and message length
405   0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
406   0xb7, 0xe7, 0xa7, 0x01,  // }
407   0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
408   0xfa, 0x87, 0xdf, 0xae,  // }
409   0x80, 0x22, 0x00, 0x10,  //    SOFTWARE attribute header
410   0x53, 0x54, 0x55, 0x4e,  // }
411   0x20, 0x74, 0x65, 0x73,  // }  User-agent...
412   0x74, 0x20, 0x63, 0x6c,  // }  ...name
413   0x69, 0x65, 0x6e, 0x74,  // }
414   0x00, 0x24, 0x00, 0x04,  //    PRIORITY attribute header
415   0x6e, 0x00, 0x01, 0xff,  //    ICE priority value
416   0x80, 0x29, 0x00, 0x08,  //    ICE-CONTROLLED attribute header
417   0x93, 0x2f, 0xf9, 0xb1,  // }  Pseudo-random tie breaker...
418   0x51, 0x26, 0x3b, 0x36,  // }   ...for ICE control
419   0x00, 0x06, 0x00, 0x09,  //    USERNAME attribute header
420   0x65, 0x76, 0x74, 0x6a,  // }
421   0x3a, 0x68, 0x36, 0x76,  // }  Username (9 bytes) and padding (3 bytes)
422   0x59, 0x20, 0x20, 0x20   // }
423 };
424
425 // This HMAC differs from the RFC 5769 SampleRequest message. This differs
426 // because spec uses 0x20 for the padding where as our implementation uses 0.
427 static const unsigned char kCalculatedHmac1[] = {
428   0x79, 0x07, 0xc2, 0xd2,  // }
429   0xed, 0xbf, 0xea, 0x48,  // }
430   0x0e, 0x4c, 0x76, 0xd8,  // }  HMAC-SHA1 fingerprint
431   0x29, 0x62, 0xd5, 0xc3,  // }
432   0x74, 0x2a, 0xf9, 0xe3   // }
433 };
434
435 // Length parameter is changed to 0x1c from 0x3c.
436 // AddMessageIntegrity will add MI information and update the length param
437 // accordingly.
438 static const unsigned char kRfc5769SampleResponseWithoutMI[] = {
439   0x01, 0x01, 0x00, 0x1c,  //    Response type and message length
440   0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
441   0xb7, 0xe7, 0xa7, 0x01,  // }
442   0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
443   0xfa, 0x87, 0xdf, 0xae,  // }
444   0x80, 0x22, 0x00, 0x0b,  //    SOFTWARE attribute header
445   0x74, 0x65, 0x73, 0x74,  // }
446   0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
447   0x74, 0x6f, 0x72, 0x20,  // }
448   0x00, 0x20, 0x00, 0x08,  //    XOR-MAPPED-ADDRESS attribute header
449   0x00, 0x01, 0xa1, 0x47,  //    Address family (IPv4) and xor'd mapped port
450   0xe1, 0x12, 0xa6, 0x43   //    Xor'd mapped IPv4 address
451 };
452
453 // This HMAC differs from the RFC 5769 SampleResponse message. This differs
454 // because spec uses 0x20 for the padding where as our implementation uses 0.
455 static const unsigned char kCalculatedHmac2[] = {
456   0x5d, 0x6b, 0x58, 0xbe,  // }
457   0xad, 0x94, 0xe0, 0x7e,  // }
458   0xef, 0x0d, 0xfc, 0x12,  // }  HMAC-SHA1 fingerprint
459   0x82, 0xa2, 0xbd, 0x08,  // }
460   0x43, 0x14, 0x10, 0x28   // }
461 };
462
463 // A transaction ID without the 'magic cookie' portion
464 // pjnat's test programs use this transaction ID a lot.
465 const unsigned char kTestTransactionId1[] = { 0x029, 0x01f, 0x0cd, 0x07c,
466                                               0x0ba, 0x058, 0x0ab, 0x0d7,
467                                               0x0f2, 0x041, 0x001, 0x000 };
468
469 // They use this one sometimes too.
470 const unsigned char kTestTransactionId2[] = { 0x0e3, 0x0a9, 0x046, 0x0e1,
471                                               0x07c, 0x000, 0x0c2, 0x062,
472                                               0x054, 0x008, 0x001, 0x000 };
473
474 const in6_addr kIPv6TestAddress1 = { { { 0x24, 0x01, 0xfa, 0x00,
475                                          0x00, 0x04, 0x10, 0x00,
476                                          0xbe, 0x30, 0x5b, 0xff,
477                                          0xfe, 0xe5, 0x00, 0xc3 } } };
478 const in6_addr kIPv6TestAddress2 = { { { 0x24, 0x01, 0xfa, 0x00,
479                                          0x00, 0x04, 0x10, 0x12,
480                                          0x06, 0x0c, 0xce, 0xff,
481                                          0xfe, 0x1f, 0x61, 0xa4 } } };
482
483 #ifdef POSIX
484 const in_addr kIPv4TestAddress1 =  { 0xe64417ac };
485 #elif defined WIN32
486 // Windows in_addr has a union with a uchar[] array first.
487 const in_addr kIPv4TestAddress1 =  { { 0x0ac, 0x017, 0x044, 0x0e6 } };
488 #endif
489 const char kTestUserName1[] = "abcdefgh";
490 const char kTestUserName2[] = "abc";
491 const char kTestErrorReason[] = "Unauthorized";
492 const int kTestErrorClass = 4;
493 const int kTestErrorNumber = 1;
494 const int kTestErrorCode = 401;
495
496 const int kTestMessagePort1 = 59977;
497 const int kTestMessagePort2 = 47233;
498 const int kTestMessagePort3 = 56743;
499 const int kTestMessagePort4 = 40444;
500
501 #define ReadStunMessage(X, Y) ReadStunMessageTestCase(X, Y, sizeof(Y));
502
503 // Test that the GetStun*Type and IsStun*Type methods work as expected.
504 TEST_F(StunTest, MessageTypes) {
505   EXPECT_EQ(STUN_BINDING_RESPONSE,
506       GetStunSuccessResponseType(STUN_BINDING_REQUEST));
507   EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE,
508       GetStunErrorResponseType(STUN_BINDING_REQUEST));
509   EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_INDICATION));
510   EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_RESPONSE));
511   EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_ERROR_RESPONSE));
512   EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_INDICATION));
513   EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_RESPONSE));
514   EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_ERROR_RESPONSE));
515
516   int types[] = {
517     STUN_BINDING_REQUEST, STUN_BINDING_INDICATION,
518     STUN_BINDING_RESPONSE, STUN_BINDING_ERROR_RESPONSE
519   };
520   for (int i = 0; i < ARRAY_SIZE(types); ++i) {
521     EXPECT_EQ(i == 0, IsStunRequestType(types[i]));
522     EXPECT_EQ(i == 1, IsStunIndicationType(types[i]));
523     EXPECT_EQ(i == 2, IsStunSuccessResponseType(types[i]));
524     EXPECT_EQ(i == 3, IsStunErrorResponseType(types[i]));
525     EXPECT_EQ(1, types[i] & 0xFEEF);
526   }
527 }
528
529 TEST_F(StunTest, ReadMessageWithIPv4AddressAttribute) {
530   StunMessage msg;
531   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4MappedAddress);
532   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
533   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
534
535   const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
536   rtc::IPAddress test_address(kIPv4TestAddress1);
537   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
538                             kTestMessagePort4, test_address);
539 }
540
541 TEST_F(StunTest, ReadMessageWithIPv4XorAddressAttribute) {
542   StunMessage msg;
543   StunMessage msg2;
544   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);
545   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
546   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
547
548   const StunAddressAttribute* addr =
549       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
550   rtc::IPAddress test_address(kIPv4TestAddress1);
551   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
552                             kTestMessagePort3, test_address);
553 }
554
555 TEST_F(StunTest, ReadMessageWithIPv6AddressAttribute) {
556   StunMessage msg;
557   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
558   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
559   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
560
561   rtc::IPAddress test_address(kIPv6TestAddress1);
562
563   const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
564   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
565                             kTestMessagePort2, test_address);
566 }
567
568 TEST_F(StunTest, ReadMessageWithInvalidAddressAttribute) {
569   StunMessage msg;
570   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
571   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
572   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
573
574   rtc::IPAddress test_address(kIPv6TestAddress1);
575
576   const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
577   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
578                             kTestMessagePort2, test_address);
579 }
580
581 TEST_F(StunTest, ReadMessageWithIPv6XorAddressAttribute) {
582   StunMessage msg;
583   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);
584
585   rtc::IPAddress test_address(kIPv6TestAddress1);
586
587   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
588   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
589
590   const StunAddressAttribute* addr =
591       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
592   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
593                             kTestMessagePort1, test_address);
594 }
595
596 // Read the RFC5389 fields from the RFC5769 sample STUN request.
597 TEST_F(StunTest, ReadRfc5769RequestMessage) {
598   StunMessage msg;
599   size_t size = ReadStunMessage(&msg, kRfc5769SampleRequest);
600   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
601   CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
602                          kStunTransactionIdLength);
603
604   const StunByteStringAttribute* software =
605       msg.GetByteString(STUN_ATTR_SOFTWARE);
606   ASSERT_TRUE(software != NULL);
607   EXPECT_EQ(kRfc5769SampleMsgClientSoftware, software->GetString());
608
609   const StunByteStringAttribute* username =
610       msg.GetByteString(STUN_ATTR_USERNAME);
611   ASSERT_TRUE(username != NULL);
612   EXPECT_EQ(kRfc5769SampleMsgUsername, username->GetString());
613
614   // Actual M-I value checked in a later test.
615   ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
616
617   // Fingerprint checked in a later test, but double-check the value here.
618   const StunUInt32Attribute* fingerprint =
619       msg.GetUInt32(STUN_ATTR_FINGERPRINT);
620   ASSERT_TRUE(fingerprint != NULL);
621   EXPECT_EQ(0xe57a3bcf, fingerprint->value());
622 }
623
624 // Read the RFC5389 fields from the RFC5769 sample STUN response.
625 TEST_F(StunTest, ReadRfc5769ResponseMessage) {
626   StunMessage msg;
627   size_t size = ReadStunMessage(&msg, kRfc5769SampleResponse);
628   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
629   CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
630                          kStunTransactionIdLength);
631
632   const StunByteStringAttribute* software =
633       msg.GetByteString(STUN_ATTR_SOFTWARE);
634   ASSERT_TRUE(software != NULL);
635   EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->GetString());
636
637   const StunAddressAttribute* mapped_address =
638       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
639   ASSERT_TRUE(mapped_address != NULL);
640   EXPECT_EQ(kRfc5769SampleMsgMappedAddress, mapped_address->GetAddress());
641
642   // Actual M-I and fingerprint checked in later tests.
643   ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
644   ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
645 }
646
647 // Read the RFC5389 fields from the RFC5769 sample STUN response for IPv6.
648 TEST_F(StunTest, ReadRfc5769ResponseMessageIPv6) {
649   StunMessage msg;
650   size_t size = ReadStunMessage(&msg, kRfc5769SampleResponseIPv6);
651   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
652   CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
653                          kStunTransactionIdLength);
654
655   const StunByteStringAttribute* software =
656       msg.GetByteString(STUN_ATTR_SOFTWARE);
657   ASSERT_TRUE(software != NULL);
658   EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->GetString());
659
660   const StunAddressAttribute* mapped_address =
661       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
662   ASSERT_TRUE(mapped_address != NULL);
663   EXPECT_EQ(kRfc5769SampleMsgIPv6MappedAddress, mapped_address->GetAddress());
664
665   // Actual M-I and fingerprint checked in later tests.
666   ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
667   ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
668 }
669
670 // Read the RFC5389 fields from the RFC5769 sample STUN response with auth.
671 TEST_F(StunTest, ReadRfc5769RequestMessageLongTermAuth) {
672   StunMessage msg;
673   size_t size = ReadStunMessage(&msg, kRfc5769SampleRequestLongTermAuth);
674   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
675   CheckStunTransactionID(msg, kRfc5769SampleMsgWithAuthTransactionId,
676                          kStunTransactionIdLength);
677
678   const StunByteStringAttribute* username =
679       msg.GetByteString(STUN_ATTR_USERNAME);
680   ASSERT_TRUE(username != NULL);
681   EXPECT_EQ(kRfc5769SampleMsgWithAuthUsername, username->GetString());
682
683   const StunByteStringAttribute* nonce =
684       msg.GetByteString(STUN_ATTR_NONCE);
685   ASSERT_TRUE(nonce != NULL);
686   EXPECT_EQ(kRfc5769SampleMsgWithAuthNonce, nonce->GetString());
687
688   const StunByteStringAttribute* realm =
689       msg.GetByteString(STUN_ATTR_REALM);
690   ASSERT_TRUE(realm != NULL);
691   EXPECT_EQ(kRfc5769SampleMsgWithAuthRealm, realm->GetString());
692
693   // No fingerprint, actual M-I checked in later tests.
694   ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
695   ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) == NULL);
696 }
697
698 // The RFC3489 packet in this test is the same as
699 // kStunMessageWithIPv4MappedAddress, but with a different value where the
700 // magic cookie was.
701 TEST_F(StunTest, ReadLegacyMessage) {
702   unsigned char rfc3489_packet[sizeof(kStunMessageWithIPv4MappedAddress)];
703   memcpy(rfc3489_packet, kStunMessageWithIPv4MappedAddress,
704       sizeof(kStunMessageWithIPv4MappedAddress));
705   // Overwrite the magic cookie here.
706   memcpy(&rfc3489_packet[4], "ABCD", 4);
707
708   StunMessage msg;
709   size_t size = ReadStunMessage(&msg, rfc3489_packet);
710   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
711   CheckStunTransactionID(msg, &rfc3489_packet[4], kStunTransactionIdLength + 4);
712
713   const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
714   rtc::IPAddress test_address(kIPv4TestAddress1);
715   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
716                             kTestMessagePort4, test_address);
717 }
718
719 TEST_F(StunTest, SetIPv6XorAddressAttributeOwner) {
720   StunMessage msg;
721   StunMessage msg2;
722   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);
723
724   rtc::IPAddress test_address(kIPv6TestAddress1);
725
726   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
727   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
728
729   const StunAddressAttribute* addr =
730       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
731   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
732                             kTestMessagePort1, test_address);
733
734   // Owner with a different transaction ID.
735   msg2.SetTransactionID("ABCDABCDABCD");
736   StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, NULL);
737   addr2.SetIP(addr->ipaddr());
738   addr2.SetPort(addr->port());
739   addr2.SetOwner(&msg2);
740   // The internal IP address shouldn't change.
741   ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
742
743   rtc::ByteBuffer correct_buf;
744   rtc::ByteBuffer wrong_buf;
745   EXPECT_TRUE(addr->Write(&correct_buf));
746   EXPECT_TRUE(addr2.Write(&wrong_buf));
747   // But when written out, the buffers should look different.
748   ASSERT_NE(0,
749             memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length()));
750   // And when reading a known good value, the address should be wrong.
751   addr2.Read(&correct_buf);
752   ASSERT_NE(addr->ipaddr(), addr2.ipaddr());
753   addr2.SetIP(addr->ipaddr());
754   addr2.SetPort(addr->port());
755   // Try writing with no owner at all, should fail and write nothing.
756   addr2.SetOwner(NULL);
757   ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
758   wrong_buf.Consume(wrong_buf.Length());
759   EXPECT_FALSE(addr2.Write(&wrong_buf));
760   ASSERT_EQ(0U, wrong_buf.Length());
761 }
762
763 TEST_F(StunTest, SetIPv4XorAddressAttributeOwner) {
764   // Unlike the IPv6XorAddressAttributeOwner test, IPv4 XOR address attributes
765   // should _not_ be affected by a change in owner. IPv4 XOR address uses the
766   // magic cookie value which is fixed.
767   StunMessage msg;
768   StunMessage msg2;
769   size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);
770
771   rtc::IPAddress test_address(kIPv4TestAddress1);
772
773   CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
774   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
775
776   const StunAddressAttribute* addr =
777       msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
778   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
779                             kTestMessagePort3, test_address);
780
781   // Owner with a different transaction ID.
782   msg2.SetTransactionID("ABCDABCDABCD");
783   StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, NULL);
784   addr2.SetIP(addr->ipaddr());
785   addr2.SetPort(addr->port());
786   addr2.SetOwner(&msg2);
787   // The internal IP address shouldn't change.
788   ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
789
790   rtc::ByteBuffer correct_buf;
791   rtc::ByteBuffer wrong_buf;
792   EXPECT_TRUE(addr->Write(&correct_buf));
793   EXPECT_TRUE(addr2.Write(&wrong_buf));
794   // The same address data should be written.
795   ASSERT_EQ(0,
796             memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length()));
797   // And an attribute should be able to un-XOR an address belonging to a message
798   // with a different transaction ID.
799   EXPECT_TRUE(addr2.Read(&correct_buf));
800   ASSERT_EQ(addr->ipaddr(), addr2.ipaddr());
801
802   // However, no owner is still an error, should fail and write nothing.
803   addr2.SetOwner(NULL);
804   ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
805   wrong_buf.Consume(wrong_buf.Length());
806   EXPECT_FALSE(addr2.Write(&wrong_buf));
807 }
808
809 TEST_F(StunTest, CreateIPv6AddressAttribute) {
810   rtc::IPAddress test_ip(kIPv6TestAddress2);
811
812   StunAddressAttribute* addr =
813       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
814   rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
815   addr->SetAddress(test_addr);
816
817   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6,
818                             kTestMessagePort2, test_ip);
819   delete addr;
820 }
821
822 TEST_F(StunTest, CreateIPv4AddressAttribute) {
823   struct in_addr test_in_addr;
824   test_in_addr.s_addr = 0xBEB0B0BE;
825   rtc::IPAddress test_ip(test_in_addr);
826
827   StunAddressAttribute* addr =
828       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
829   rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
830   addr->SetAddress(test_addr);
831
832   CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4,
833                             kTestMessagePort2, test_ip);
834   delete addr;
835 }
836
837 // Test that we don't care what order we set the parts of an address
838 TEST_F(StunTest, CreateAddressInArbitraryOrder) {
839   StunAddressAttribute* addr =
840   StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
841   // Port first
842   addr->SetPort(kTestMessagePort1);
843   addr->SetIP(rtc::IPAddress(kIPv4TestAddress1));
844   ASSERT_EQ(kTestMessagePort1, addr->port());
845   ASSERT_EQ(rtc::IPAddress(kIPv4TestAddress1), addr->ipaddr());
846
847   StunAddressAttribute* addr2 =
848   StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
849   // IP first
850   addr2->SetIP(rtc::IPAddress(kIPv4TestAddress1));
851   addr2->SetPort(kTestMessagePort2);
852   ASSERT_EQ(kTestMessagePort2, addr2->port());
853   ASSERT_EQ(rtc::IPAddress(kIPv4TestAddress1), addr2->ipaddr());
854
855   delete addr;
856   delete addr2;
857 }
858
859 TEST_F(StunTest, WriteMessageWithIPv6AddressAttribute) {
860   StunMessage msg;
861   size_t size = sizeof(kStunMessageWithIPv6MappedAddress);
862
863   rtc::IPAddress test_ip(kIPv6TestAddress1);
864
865   msg.SetType(STUN_BINDING_REQUEST);
866   msg.SetTransactionID(
867       std::string(reinterpret_cast<const char*>(kTestTransactionId1),
868                   kStunTransactionIdLength));
869   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
870
871   StunAddressAttribute* addr =
872       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
873   rtc::SocketAddress test_addr(test_ip, kTestMessagePort2);
874   addr->SetAddress(test_addr);
875   EXPECT_TRUE(msg.AddAttribute(addr));
876
877   CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
878
879   rtc::ByteBuffer out;
880   EXPECT_TRUE(msg.Write(&out));
881   ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6MappedAddress));
882   int len1 = static_cast<int>(out.Length());
883   std::string bytes;
884   out.ReadString(&bytes, len1);
885   ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv6MappedAddress, len1));
886 }
887
888 TEST_F(StunTest, WriteMessageWithIPv4AddressAttribute) {
889   StunMessage msg;
890   size_t size = sizeof(kStunMessageWithIPv4MappedAddress);
891
892   rtc::IPAddress test_ip(kIPv4TestAddress1);
893
894   msg.SetType(STUN_BINDING_RESPONSE);
895   msg.SetTransactionID(
896       std::string(reinterpret_cast<const char*>(kTestTransactionId1),
897                   kStunTransactionIdLength));
898   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
899
900   StunAddressAttribute* addr =
901       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
902   rtc::SocketAddress test_addr(test_ip, kTestMessagePort4);
903   addr->SetAddress(test_addr);
904   EXPECT_TRUE(msg.AddAttribute(addr));
905
906   CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
907
908   rtc::ByteBuffer out;
909   EXPECT_TRUE(msg.Write(&out));
910   ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4MappedAddress));
911   int len1 = static_cast<int>(out.Length());
912   std::string bytes;
913   out.ReadString(&bytes, len1);
914   ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv4MappedAddress, len1));
915 }
916
917 TEST_F(StunTest, WriteMessageWithIPv6XorAddressAttribute) {
918   StunMessage msg;
919   size_t size = sizeof(kStunMessageWithIPv6XorMappedAddress);
920
921   rtc::IPAddress test_ip(kIPv6TestAddress1);
922
923   msg.SetType(STUN_BINDING_RESPONSE);
924   msg.SetTransactionID(
925       std::string(reinterpret_cast<const char*>(kTestTransactionId2),
926                   kStunTransactionIdLength));
927   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
928
929   StunAddressAttribute* addr =
930       StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
931   rtc::SocketAddress test_addr(test_ip, kTestMessagePort1);
932   addr->SetAddress(test_addr);
933   EXPECT_TRUE(msg.AddAttribute(addr));
934
935   CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
936
937   rtc::ByteBuffer out;
938   EXPECT_TRUE(msg.Write(&out));
939   ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6XorMappedAddress));
940   int len1 = static_cast<int>(out.Length());
941   std::string bytes;
942   out.ReadString(&bytes, len1);
943   ASSERT_EQ(0,
944             memcmp(bytes.c_str(), kStunMessageWithIPv6XorMappedAddress, len1));
945 }
946
947 TEST_F(StunTest, WriteMessageWithIPv4XoreAddressAttribute) {
948   StunMessage msg;
949   size_t size = sizeof(kStunMessageWithIPv4XorMappedAddress);
950
951   rtc::IPAddress test_ip(kIPv4TestAddress1);
952
953   msg.SetType(STUN_BINDING_RESPONSE);
954   msg.SetTransactionID(
955       std::string(reinterpret_cast<const char*>(kTestTransactionId1),
956                   kStunTransactionIdLength));
957   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
958
959   StunAddressAttribute* addr =
960       StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
961   rtc::SocketAddress test_addr(test_ip, kTestMessagePort3);
962   addr->SetAddress(test_addr);
963   EXPECT_TRUE(msg.AddAttribute(addr));
964
965   CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
966
967   rtc::ByteBuffer out;
968   EXPECT_TRUE(msg.Write(&out));
969   ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4XorMappedAddress));
970   int len1 = static_cast<int>(out.Length());
971   std::string bytes;
972   out.ReadString(&bytes, len1);
973   ASSERT_EQ(0,
974             memcmp(bytes.c_str(), kStunMessageWithIPv4XorMappedAddress, len1));
975 }
976
977 TEST_F(StunTest, ReadByteStringAttribute) {
978   StunMessage msg;
979   size_t size = ReadStunMessage(&msg, kStunMessageWithByteStringAttribute);
980
981   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
982   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
983   const StunByteStringAttribute* username =
984       msg.GetByteString(STUN_ATTR_USERNAME);
985   ASSERT_TRUE(username != NULL);
986   EXPECT_EQ(kTestUserName1, username->GetString());
987 }
988
989 TEST_F(StunTest, ReadPaddedByteStringAttribute) {
990   StunMessage msg;
991   size_t size = ReadStunMessage(&msg,
992                                 kStunMessageWithPaddedByteStringAttribute);
993   ASSERT_NE(0U, size);
994   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
995   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
996   const StunByteStringAttribute* username =
997       msg.GetByteString(STUN_ATTR_USERNAME);
998   ASSERT_TRUE(username != NULL);
999   EXPECT_EQ(kTestUserName2, username->GetString());
1000 }
1001
1002 TEST_F(StunTest, ReadErrorCodeAttribute) {
1003   StunMessage msg;
1004   size_t size = ReadStunMessage(&msg, kStunMessageWithErrorAttribute);
1005
1006   CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, size);
1007   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
1008   const StunErrorCodeAttribute* errorcode = msg.GetErrorCode();
1009   ASSERT_TRUE(errorcode != NULL);
1010   EXPECT_EQ(kTestErrorClass, errorcode->eclass());
1011   EXPECT_EQ(kTestErrorNumber, errorcode->number());
1012   EXPECT_EQ(kTestErrorReason, errorcode->reason());
1013   EXPECT_EQ(kTestErrorCode, errorcode->code());
1014 }
1015
1016 TEST_F(StunTest, ReadMessageWithAUInt16ListAttribute) {
1017   StunMessage msg;
1018   size_t size = ReadStunMessage(&msg, kStunMessageWithUInt16ListAttribute);
1019   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
1020   const StunUInt16ListAttribute* types = msg.GetUnknownAttributes();
1021   ASSERT_TRUE(types != NULL);
1022   EXPECT_EQ(3U, types->Size());
1023   EXPECT_EQ(0x1U, types->GetType(0));
1024   EXPECT_EQ(0x1000U, types->GetType(1));
1025   EXPECT_EQ(0xAB0CU, types->GetType(2));
1026 }
1027
1028 TEST_F(StunTest, ReadMessageWithAnUnknownAttribute) {
1029   StunMessage msg;
1030   size_t size = ReadStunMessage(&msg, kStunMessageWithUnknownAttribute);
1031   CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
1032
1033   // Parsing should have succeeded and there should be a USERNAME attribute
1034   const StunByteStringAttribute* username =
1035       msg.GetByteString(STUN_ATTR_USERNAME);
1036   ASSERT_TRUE(username != NULL);
1037   EXPECT_EQ(kTestUserName2, username->GetString());
1038 }
1039
1040 TEST_F(StunTest, WriteMessageWithAnErrorCodeAttribute) {
1041   StunMessage msg;
1042   size_t size = sizeof(kStunMessageWithErrorAttribute);
1043
1044   msg.SetType(STUN_BINDING_ERROR_RESPONSE);
1045   msg.SetTransactionID(
1046       std::string(reinterpret_cast<const char*>(kTestTransactionId1),
1047                   kStunTransactionIdLength));
1048   CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
1049   StunErrorCodeAttribute* errorcode = StunAttribute::CreateErrorCode();
1050   errorcode->SetCode(kTestErrorCode);
1051   errorcode->SetReason(kTestErrorReason);
1052   EXPECT_TRUE(msg.AddAttribute(errorcode));
1053   CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, (size - 20));
1054
1055   rtc::ByteBuffer out;
1056   EXPECT_TRUE(msg.Write(&out));
1057   ASSERT_EQ(size, out.Length());
1058   // No padding.
1059   ASSERT_EQ(0, memcmp(out.Data(), kStunMessageWithErrorAttribute, size));
1060 }
1061
1062 TEST_F(StunTest, WriteMessageWithAUInt16ListAttribute) {
1063   StunMessage msg;
1064   size_t size = sizeof(kStunMessageWithUInt16ListAttribute);
1065
1066   msg.SetType(STUN_BINDING_REQUEST);
1067   msg.SetTransactionID(
1068       std::string(reinterpret_cast<const char*>(kTestTransactionId2),
1069                   kStunTransactionIdLength));
1070   CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
1071   StunUInt16ListAttribute* list = StunAttribute::CreateUnknownAttributes();
1072   list->AddType(0x1U);
1073   list->AddType(0x1000U);
1074   list->AddType(0xAB0CU);
1075   EXPECT_TRUE(msg.AddAttribute(list));
1076   CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
1077
1078   rtc::ByteBuffer out;
1079   EXPECT_TRUE(msg.Write(&out));
1080   ASSERT_EQ(size, out.Length());
1081   // Check everything up to the padding.
1082   ASSERT_EQ(0,
1083             memcmp(out.Data(), kStunMessageWithUInt16ListAttribute, size - 2));
1084 }
1085
1086 // Test that we fail to read messages with invalid lengths.
1087 void CheckFailureToRead(const unsigned char* testcase, size_t length) {
1088   StunMessage msg;
1089   const char* input = reinterpret_cast<const char*>(testcase);
1090   rtc::ByteBuffer buf(input, length);
1091   ASSERT_FALSE(msg.Read(&buf));
1092 }
1093
1094 TEST_F(StunTest, FailToReadInvalidMessages) {
1095   CheckFailureToRead(kStunMessageWithZeroLength,
1096                      kRealLengthOfInvalidLengthTestCases);
1097   CheckFailureToRead(kStunMessageWithSmallLength,
1098                      kRealLengthOfInvalidLengthTestCases);
1099   CheckFailureToRead(kStunMessageWithExcessLength,
1100                      kRealLengthOfInvalidLengthTestCases);
1101 }
1102
1103 // Test that we properly fail to read a non-STUN message.
1104 TEST_F(StunTest, FailToReadRtcpPacket) {
1105   CheckFailureToRead(kRtcpPacket, sizeof(kRtcpPacket));
1106 }
1107
1108 // Check our STUN message validation code against the RFC5769 test messages.
1109 TEST_F(StunTest, ValidateMessageIntegrity) {
1110   // Try the messages from RFC 5769.
1111   EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1112       reinterpret_cast<const char*>(kRfc5769SampleRequest),
1113       sizeof(kRfc5769SampleRequest),
1114       kRfc5769SampleMsgPassword));
1115   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1116       reinterpret_cast<const char*>(kRfc5769SampleRequest),
1117       sizeof(kRfc5769SampleRequest),
1118       "InvalidPassword"));
1119
1120   EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1121       reinterpret_cast<const char*>(kRfc5769SampleResponse),
1122       sizeof(kRfc5769SampleResponse),
1123       kRfc5769SampleMsgPassword));
1124   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1125       reinterpret_cast<const char*>(kRfc5769SampleResponse),
1126       sizeof(kRfc5769SampleResponse),
1127       "InvalidPassword"));
1128
1129   EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1130       reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
1131       sizeof(kRfc5769SampleResponseIPv6),
1132       kRfc5769SampleMsgPassword));
1133   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1134       reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
1135       sizeof(kRfc5769SampleResponseIPv6),
1136       "InvalidPassword"));
1137
1138   // We first need to compute the key for the long-term authentication HMAC.
1139   std::string key;
1140   ComputeStunCredentialHash(kRfc5769SampleMsgWithAuthUsername,
1141       kRfc5769SampleMsgWithAuthRealm, kRfc5769SampleMsgWithAuthPassword, &key);
1142   EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1143       reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
1144       sizeof(kRfc5769SampleRequestLongTermAuth), key));
1145   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1146       reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
1147       sizeof(kRfc5769SampleRequestLongTermAuth),
1148       "InvalidPassword"));
1149
1150   // Try some edge cases.
1151   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1152       reinterpret_cast<const char*>(kStunMessageWithZeroLength),
1153       sizeof(kStunMessageWithZeroLength),
1154       kRfc5769SampleMsgPassword));
1155   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1156       reinterpret_cast<const char*>(kStunMessageWithExcessLength),
1157       sizeof(kStunMessageWithExcessLength),
1158       kRfc5769SampleMsgPassword));
1159   EXPECT_FALSE(StunMessage::ValidateMessageIntegrity(
1160       reinterpret_cast<const char*>(kStunMessageWithSmallLength),
1161       sizeof(kStunMessageWithSmallLength),
1162       kRfc5769SampleMsgPassword));
1163
1164   // Test that munging a single bit anywhere in the message causes the
1165   // message-integrity check to fail, unless it is after the M-I attribute.
1166   char buf[sizeof(kRfc5769SampleRequest)];
1167   memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest));
1168   for (size_t i = 0; i < sizeof(buf); ++i) {
1169     buf[i] ^= 0x01;
1170     if (i > 0)
1171       buf[i - 1] ^= 0x01;
1172     EXPECT_EQ(i >= sizeof(buf) - 8, StunMessage::ValidateMessageIntegrity(
1173         buf, sizeof(buf), kRfc5769SampleMsgPassword));
1174   }
1175 }
1176
1177 // Validate that we generate correct MESSAGE-INTEGRITY attributes.
1178 // Note the use of IceMessage instead of StunMessage; this is necessary because
1179 // the RFC5769 test messages used include attributes not found in basic STUN.
1180 TEST_F(StunTest, AddMessageIntegrity) {
1181   IceMessage msg;
1182   rtc::ByteBuffer buf(
1183       reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
1184       sizeof(kRfc5769SampleRequestWithoutMI));
1185   EXPECT_TRUE(msg.Read(&buf));
1186   EXPECT_TRUE(msg.AddMessageIntegrity(kRfc5769SampleMsgPassword));
1187   const StunByteStringAttribute* mi_attr =
1188       msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
1189   EXPECT_EQ(20U, mi_attr->length());
1190   EXPECT_EQ(0, memcmp(
1191       mi_attr->bytes(), kCalculatedHmac1, sizeof(kCalculatedHmac1)));
1192
1193   rtc::ByteBuffer buf1;
1194   EXPECT_TRUE(msg.Write(&buf1));
1195   EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1196         reinterpret_cast<const char*>(buf1.Data()), buf1.Length(),
1197         kRfc5769SampleMsgPassword));
1198
1199   IceMessage msg2;
1200   rtc::ByteBuffer buf2(
1201       reinterpret_cast<const char*>(kRfc5769SampleResponseWithoutMI),
1202       sizeof(kRfc5769SampleResponseWithoutMI));
1203   EXPECT_TRUE(msg2.Read(&buf2));
1204   EXPECT_TRUE(msg2.AddMessageIntegrity(kRfc5769SampleMsgPassword));
1205   const StunByteStringAttribute* mi_attr2 =
1206       msg2.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
1207   EXPECT_EQ(20U, mi_attr2->length());
1208   EXPECT_EQ(
1209       0, memcmp(mi_attr2->bytes(), kCalculatedHmac2, sizeof(kCalculatedHmac2)));
1210
1211   rtc::ByteBuffer buf3;
1212   EXPECT_TRUE(msg2.Write(&buf3));
1213   EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1214         reinterpret_cast<const char*>(buf3.Data()), buf3.Length(),
1215         kRfc5769SampleMsgPassword));
1216 }
1217
1218 // Check our STUN message validation code against the RFC5769 test messages.
1219 TEST_F(StunTest, ValidateFingerprint) {
1220   EXPECT_TRUE(StunMessage::ValidateFingerprint(
1221       reinterpret_cast<const char*>(kRfc5769SampleRequest),
1222       sizeof(kRfc5769SampleRequest)));
1223   EXPECT_TRUE(StunMessage::ValidateFingerprint(
1224       reinterpret_cast<const char*>(kRfc5769SampleResponse),
1225       sizeof(kRfc5769SampleResponse)));
1226   EXPECT_TRUE(StunMessage::ValidateFingerprint(
1227       reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
1228       sizeof(kRfc5769SampleResponseIPv6)));
1229
1230   EXPECT_FALSE(StunMessage::ValidateFingerprint(
1231       reinterpret_cast<const char*>(kStunMessageWithZeroLength),
1232       sizeof(kStunMessageWithZeroLength)));
1233   EXPECT_FALSE(StunMessage::ValidateFingerprint(
1234       reinterpret_cast<const char*>(kStunMessageWithExcessLength),
1235       sizeof(kStunMessageWithExcessLength)));
1236   EXPECT_FALSE(StunMessage::ValidateFingerprint(
1237       reinterpret_cast<const char*>(kStunMessageWithSmallLength),
1238       sizeof(kStunMessageWithSmallLength)));
1239
1240   // Test that munging a single bit anywhere in the message causes the
1241   // fingerprint check to fail.
1242   char buf[sizeof(kRfc5769SampleRequest)];
1243   memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest));
1244   for (size_t i = 0; i < sizeof(buf); ++i) {
1245     buf[i] ^= 0x01;
1246     if (i > 0)
1247       buf[i - 1] ^= 0x01;
1248     EXPECT_FALSE(StunMessage::ValidateFingerprint(buf, sizeof(buf)));
1249   }
1250   // Put them all back to normal and the check should pass again.
1251   buf[sizeof(buf) - 1] ^= 0x01;
1252   EXPECT_TRUE(StunMessage::ValidateFingerprint(buf, sizeof(buf)));
1253 }
1254
1255 TEST_F(StunTest, AddFingerprint) {
1256   IceMessage msg;
1257   rtc::ByteBuffer buf(
1258       reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
1259       sizeof(kRfc5769SampleRequestWithoutMI));
1260   EXPECT_TRUE(msg.Read(&buf));
1261   EXPECT_TRUE(msg.AddFingerprint());
1262
1263   rtc::ByteBuffer buf1;
1264   EXPECT_TRUE(msg.Write(&buf1));
1265   EXPECT_TRUE(StunMessage::ValidateFingerprint(
1266       reinterpret_cast<const char*>(buf1.Data()), buf1.Length()));
1267 }
1268
1269 // Sample "GTURN" relay message.
1270 static const unsigned char kRelayMessage[] = {
1271   0x00, 0x01, 0x00, 88,    // message header
1272   0x21, 0x12, 0xA4, 0x42,  // magic cookie
1273   '0', '1', '2', '3',      // transaction id
1274   '4', '5', '6', '7',
1275   '8', '9', 'a', 'b',
1276   0x00, 0x01, 0x00, 8,     // mapped address
1277   0x00, 0x01, 0x00, 13,
1278   0x00, 0x00, 0x00, 17,
1279   0x00, 0x06, 0x00, 12,    // username
1280   'a', 'b', 'c', 'd',
1281   'e', 'f', 'g', 'h',
1282   'i', 'j', 'k', 'l',
1283   0x00, 0x0d, 0x00, 4,     // lifetime
1284   0x00, 0x00, 0x00, 11,
1285   0x00, 0x0f, 0x00, 4,     // magic cookie
1286   0x72, 0xc6, 0x4b, 0xc6,
1287   0x00, 0x10, 0x00, 4,     // bandwidth
1288   0x00, 0x00, 0x00, 6,
1289   0x00, 0x11, 0x00, 8,     // destination address
1290   0x00, 0x01, 0x00, 13,
1291   0x00, 0x00, 0x00, 17,
1292   0x00, 0x12, 0x00, 8,     // source address 2
1293   0x00, 0x01, 0x00, 13,
1294   0x00, 0x00, 0x00, 17,
1295   0x00, 0x13, 0x00, 7,     // data
1296   'a', 'b', 'c', 'd',
1297   'e', 'f', 'g', 0         // DATA must be padded per rfc5766.
1298 };
1299
1300 // Test that we can read the GTURN-specific fields.
1301 TEST_F(StunTest, ReadRelayMessage) {
1302   RelayMessage msg, msg2;
1303
1304   const char* input = reinterpret_cast<const char*>(kRelayMessage);
1305   size_t size = sizeof(kRelayMessage);
1306   rtc::ByteBuffer buf(input, size);
1307   EXPECT_TRUE(msg.Read(&buf));
1308
1309   EXPECT_EQ(STUN_BINDING_REQUEST, msg.type());
1310   EXPECT_EQ(size - 20, msg.length());
1311   EXPECT_EQ("0123456789ab", msg.transaction_id());
1312
1313   msg2.SetType(STUN_BINDING_REQUEST);
1314   msg2.SetTransactionID("0123456789ab");
1315
1316   in_addr legacy_in_addr;
1317   legacy_in_addr.s_addr = htonl(17U);
1318   rtc::IPAddress legacy_ip(legacy_in_addr);
1319
1320   const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
1321   ASSERT_TRUE(addr != NULL);
1322   EXPECT_EQ(1, addr->family());
1323   EXPECT_EQ(13, addr->port());
1324   EXPECT_EQ(legacy_ip, addr->ipaddr());
1325
1326   StunAddressAttribute* addr2 =
1327       StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
1328   addr2->SetPort(13);
1329   addr2->SetIP(legacy_ip);
1330   EXPECT_TRUE(msg2.AddAttribute(addr2));
1331
1332   const StunByteStringAttribute* bytes = msg.GetByteString(STUN_ATTR_USERNAME);
1333   ASSERT_TRUE(bytes != NULL);
1334   EXPECT_EQ(12U, bytes->length());
1335   EXPECT_EQ("abcdefghijkl", bytes->GetString());
1336
1337   StunByteStringAttribute* bytes2 =
1338   StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
1339   bytes2->CopyBytes("abcdefghijkl");
1340   EXPECT_TRUE(msg2.AddAttribute(bytes2));
1341
1342   const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME);
1343   ASSERT_TRUE(uval != NULL);
1344   EXPECT_EQ(11U, uval->value());
1345
1346   StunUInt32Attribute* uval2 = StunAttribute::CreateUInt32(STUN_ATTR_LIFETIME);
1347   uval2->SetValue(11);
1348   EXPECT_TRUE(msg2.AddAttribute(uval2));
1349
1350   bytes = msg.GetByteString(STUN_ATTR_MAGIC_COOKIE);
1351   ASSERT_TRUE(bytes != NULL);
1352   EXPECT_EQ(4U, bytes->length());
1353   EXPECT_EQ(0,
1354             memcmp(bytes->bytes(),
1355                    TURN_MAGIC_COOKIE_VALUE,
1356                    sizeof(TURN_MAGIC_COOKIE_VALUE)));
1357
1358   bytes2 = StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE);
1359   bytes2->CopyBytes(reinterpret_cast<const char*>(TURN_MAGIC_COOKIE_VALUE),
1360                     sizeof(TURN_MAGIC_COOKIE_VALUE));
1361   EXPECT_TRUE(msg2.AddAttribute(bytes2));
1362
1363   uval = msg.GetUInt32(STUN_ATTR_BANDWIDTH);
1364   ASSERT_TRUE(uval != NULL);
1365   EXPECT_EQ(6U, uval->value());
1366
1367   uval2 = StunAttribute::CreateUInt32(STUN_ATTR_BANDWIDTH);
1368   uval2->SetValue(6);
1369   EXPECT_TRUE(msg2.AddAttribute(uval2));
1370
1371   addr = msg.GetAddress(STUN_ATTR_DESTINATION_ADDRESS);
1372   ASSERT_TRUE(addr != NULL);
1373   EXPECT_EQ(1, addr->family());
1374   EXPECT_EQ(13, addr->port());
1375   EXPECT_EQ(legacy_ip, addr->ipaddr());
1376
1377   addr2 = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
1378   addr2->SetPort(13);
1379   addr2->SetIP(legacy_ip);
1380   EXPECT_TRUE(msg2.AddAttribute(addr2));
1381
1382   addr = msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
1383   ASSERT_TRUE(addr != NULL);
1384   EXPECT_EQ(1, addr->family());
1385   EXPECT_EQ(13, addr->port());
1386   EXPECT_EQ(legacy_ip, addr->ipaddr());
1387
1388   addr2 = StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
1389   addr2->SetPort(13);
1390   addr2->SetIP(legacy_ip);
1391   EXPECT_TRUE(msg2.AddAttribute(addr2));
1392
1393   bytes = msg.GetByteString(STUN_ATTR_DATA);
1394   ASSERT_TRUE(bytes != NULL);
1395   EXPECT_EQ(7U, bytes->length());
1396   EXPECT_EQ("abcdefg", bytes->GetString());
1397
1398   bytes2 = StunAttribute::CreateByteString(STUN_ATTR_DATA);
1399   bytes2->CopyBytes("abcdefg");
1400   EXPECT_TRUE(msg2.AddAttribute(bytes2));
1401
1402   rtc::ByteBuffer out;
1403   EXPECT_TRUE(msg.Write(&out));
1404   EXPECT_EQ(size, out.Length());
1405   size_t len1 = out.Length();
1406   std::string outstring;
1407   out.ReadString(&outstring, len1);
1408   EXPECT_EQ(0, memcmp(outstring.c_str(), input, len1));
1409
1410   rtc::ByteBuffer out2;
1411   EXPECT_TRUE(msg2.Write(&out2));
1412   EXPECT_EQ(size, out2.Length());
1413   size_t len2 = out2.Length();
1414   std::string outstring2;
1415   out2.ReadString(&outstring2, len2);
1416   EXPECT_EQ(0, memcmp(outstring2.c_str(), input, len2));
1417 }
1418
1419 }  // namespace cricket