Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: trunk/src/content/browser/renderer_host/p2p/socket_host.cc

Issue 307063003: Revert 273745 "Implements RTP header dumping." due to memory leak (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/p2p/socket_host.h" 5 #include "content/browser/renderer_host/p2p/socket_host.h"
6 6
7 #include "base/sys_byteorder.h" 7 #include "base/sys_byteorder.h"
8 #include "content/browser/renderer_host/p2p/socket_host_tcp.h" 8 #include "content/browser/renderer_host/p2p/socket_host_tcp.h"
9 #include "content/browser/renderer_host/p2p/socket_host_tcp_server.h" 9 #include "content/browser/renderer_host/p2p/socket_host_tcp_server.h"
10 #include "content/browser/renderer_host/p2p/socket_host_udp.h" 10 #include "content/browser/renderer_host/p2p/socket_host_udp.h"
11 #include "content/browser/renderer_host/render_process_host_impl.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "crypto/hmac.h" 11 #include "crypto/hmac.h"
14 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" 12 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
15 #include "third_party/libjingle/source/talk/base/byteorder.h" 13 #include "third_party/libjingle/source/talk/base/byteorder.h"
16 #include "third_party/libjingle/source/talk/base/messagedigest.h" 14 #include "third_party/libjingle/source/talk/base/messagedigest.h"
17 #include "third_party/libjingle/source/talk/p2p/base/stun.h" 15 #include "third_party/libjingle/source/talk/p2p/base/stun.h"
18 16
19 namespace { 17 namespace {
20 18
21 const uint32 kStunMagicCookie = 0x2112A442; 19 const uint32 kStunMagicCookie = 0x2112A442;
22 const int kMinRtpHdrLen = 12; 20 const int kMinRtpHdrLen = 12;
(...skipping 27 matching lines...) Expand all
50 bool IsTurnSendIndicationPacket(const char* data) { 48 bool IsTurnSendIndicationPacket(const char* data) {
51 uint16 type = talk_base::GetBE16(data); 49 uint16 type = talk_base::GetBE16(data);
52 return (type == cricket::TURN_SEND_INDICATION); 50 return (type == cricket::TURN_SEND_INDICATION);
53 } 51 }
54 52
55 bool IsRtpPacket(const char* data, int len) { 53 bool IsRtpPacket(const char* data, int len) {
56 return ((*data & 0xC0) == 0x80); 54 return ((*data & 0xC0) == 0x80);
57 } 55 }
58 56
59 // Verifies rtp header and message length. 57 // Verifies rtp header and message length.
60 bool ValidateRtpHeader(const char* rtp, int length, size_t* header_length) { 58 bool ValidateRtpHeader(char* rtp, int length) {
61 if (header_length)
62 *header_length = 0;
63
64 int cc_count = rtp[0] & 0x0F; 59 int cc_count = rtp[0] & 0x0F;
65 int rtp_hdr_len_without_extn = kMinRtpHdrLen + 4 * cc_count; 60 int rtp_hdr_len_without_extn = kMinRtpHdrLen + 4 * cc_count;
66 if (rtp_hdr_len_without_extn > length) { 61 if (rtp_hdr_len_without_extn > length) {
67 return false; 62 return false;
68 } 63 }
69 64
70 // If extension bit is not set, we are done with header processing, as input 65 // If extension bit is not set, we are done with header processing, as input
71 // length is verified above. 66 // length is verified above.
72 if (!(rtp[0] & 0x10)) { 67 if (!(rtp[0] & 0x10)) {
73 if (header_length)
74 *header_length = rtp_hdr_len_without_extn;
75
76 return true; 68 return true;
77 } 69 }
78 70
79 rtp += rtp_hdr_len_without_extn; 71 rtp += rtp_hdr_len_without_extn;
80 72
81 // Getting extension profile length. 73 // Getting extension profile length.
82 // Length is in 32 bit words. 74 // Length is in 32 bit words.
83 uint16 extn_length = talk_base::GetBE16(rtp + 2) * 4; 75 uint16 extn_length = talk_base::GetBE16(rtp + 2) * 4;
84 76
85 // Verify input length against total header size. 77 // Verify input length against total header size.
86 if (rtp_hdr_len_without_extn + kRtpExtnHdrLen + extn_length > length) { 78 if (rtp_hdr_len_without_extn + kRtpExtnHdrLen + extn_length > length) {
87 return false; 79 return false;
88 } 80 }
89
90 if (header_length)
91 *header_length = rtp_hdr_len_without_extn + kRtpExtnHdrLen + extn_length;
92 return true; 81 return true;
93 } 82 }
94 83
95 void UpdateAbsSendTimeExtnValue(char* extn_data, int len, 84 void UpdateAbsSendTimeExtnValue(char* extn_data, int len,
96 uint32 abs_send_time) { 85 uint32 abs_send_time) {
97 // Absolute send time in RTP streams. 86 // Absolute send time in RTP streams.
98 // 87 //
99 // The absolute send time is signaled to the receiver in-band using the 88 // The absolute send time is signaled to the receiver in-band using the
100 // general mechanism for RTP header extensions [RFC5285]. The payload 89 // general mechanism for RTP header extensions [RFC5285]. The payload
101 // of this extension (the transmitted value) is a 24-bit unsigned integer 90 // of this extension (the transmitted value) is a 24-bit unsigned integer
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 if (options.packet_time_params.rtp_sendtime_extension_id != -1) { 199 if (options.packet_time_params.rtp_sendtime_extension_id != -1) {
211 UpdateRtpAbsSendTimeExtn( 200 UpdateRtpAbsSendTimeExtn(
212 start, rtp_length, 201 start, rtp_length,
213 options.packet_time_params.rtp_sendtime_extension_id, abs_send_time); 202 options.packet_time_params.rtp_sendtime_extension_id, abs_send_time);
214 } 203 }
215 204
216 UpdateRtpAuthTag(start, rtp_length, options); 205 UpdateRtpAuthTag(start, rtp_length, options);
217 return true; 206 return true;
218 } 207 }
219 208
220 bool GetRtpPacketStartPositionAndLength(const char* packet, 209 bool GetRtpPacketStartPositionAndLength(
221 int length, 210 char* packet, int length, int* rtp_start_pos, int* rtp_packet_length) {
222 int* rtp_start_pos,
223 int* rtp_packet_length) {
224 int rtp_begin, rtp_length; 211 int rtp_begin, rtp_length;
225 if (IsTurnChannelData(packet)) { 212 if (IsTurnChannelData(packet)) {
226 // Turn Channel Message header format. 213 // Turn Channel Message header format.
227 // 0 1 2 3 214 // 0 1 2 3
228 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 215 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
229 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 216 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
230 // | Channel Number | Length | 217 // | Channel Number | Length |
231 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 218 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
232 // | | 219 // | |
233 // / Application Data / 220 // / Application Data /
(...skipping 15 matching lines...) Expand all
249 } 236 }
250 // Validate STUN message length. 237 // Validate STUN message length.
251 int stun_msg_len = talk_base::GetBE16(&packet[2]); 238 int stun_msg_len = talk_base::GetBE16(&packet[2]);
252 if (stun_msg_len + P2PSocketHost::kStunHeaderSize != length) { 239 if (stun_msg_len + P2PSocketHost::kStunHeaderSize != length) {
253 return false; 240 return false;
254 } 241 }
255 242
256 // First skip mandatory stun header which is of 20 bytes. 243 // First skip mandatory stun header which is of 20 bytes.
257 rtp_begin = P2PSocketHost::kStunHeaderSize; 244 rtp_begin = P2PSocketHost::kStunHeaderSize;
258 // Loop through STUN attributes until we find STUN DATA attribute. 245 // Loop through STUN attributes until we find STUN DATA attribute.
259 const char* start = packet + rtp_begin; 246 char* start = packet + rtp_begin;
260 bool data_attr_present = false; 247 bool data_attr_present = false;
261 while ((packet + rtp_begin) - start < stun_msg_len) { 248 while ((packet + rtp_begin) - start < stun_msg_len) {
262 // Keep reading STUN attributes until we hit DATA attribute. 249 // Keep reading STUN attributes until we hit DATA attribute.
263 // Attribute will be a TLV structure. 250 // Attribute will be a TLV structure.
264 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 251 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
265 // | Type | Length | 252 // | Type | Length |
266 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 253 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
267 // | Value (variable) .... 254 // | Value (variable) ....
268 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 255 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
269 // The value in the length field MUST contain the length of the Value 256 // The value in the length field MUST contain the length of the Value
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 296
310 } else { 297 } else {
311 // This is a raw RTP packet. 298 // This is a raw RTP packet.
312 rtp_begin = 0; 299 rtp_begin = 0;
313 rtp_length = length; 300 rtp_length = length;
314 } 301 }
315 302
316 // Making sure we have a valid RTP packet at the end. 303 // Making sure we have a valid RTP packet at the end.
317 if (!(rtp_length < kMinRtpHdrLen) && 304 if (!(rtp_length < kMinRtpHdrLen) &&
318 IsRtpPacket(packet + rtp_begin, rtp_length) && 305 IsRtpPacket(packet + rtp_begin, rtp_length) &&
319 ValidateRtpHeader(packet + rtp_begin, rtp_length, NULL)) { 306 ValidateRtpHeader(packet + rtp_begin, rtp_length)) {
320 *rtp_start_pos = rtp_begin; 307 *rtp_start_pos = rtp_begin;
321 *rtp_packet_length = rtp_length; 308 *rtp_packet_length = rtp_length;
322 return true; 309 return true;
323 } 310 }
324 return false; 311 return false;
325 } 312 }
326 313
327 // ValidateRtpHeader must be called before this method to make sure, we have 314 // ValidateRtpHeader must be called before this method to make sure, we have
328 // a sane rtp packet. 315 // a sane rtp packet.
329 bool UpdateRtpAbsSendTimeExtn(char* rtp, int length, 316 bool UpdateRtpAbsSendTimeExtn(char* rtp, int length,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 while ((*rtp == 0) && (rtp - extn_start < extn_length)) { 382 while ((*rtp == 0) && (rtp - extn_start < extn_length)) {
396 ++rtp; 383 ++rtp;
397 } 384 }
398 } 385 }
399 } 386 }
400 return found; 387 return found;
401 } 388 }
402 389
403 } // packet_processing_helpers 390 } // packet_processing_helpers
404 391
405 P2PSocketHost::P2PSocketHost(IPC::Sender* message_sender, int socket_id) 392 P2PSocketHost::P2PSocketHost(IPC::Sender* message_sender,
393 int id)
406 : message_sender_(message_sender), 394 : message_sender_(message_sender),
407 id_(socket_id), 395 id_(id),
408 state_(STATE_UNINITIALIZED), 396 state_(STATE_UNINITIALIZED) {
409 dump_incoming_rtp_packet_(false),
410 dump_outgoing_rtp_packet_(false),
411 weak_ptr_factory_(this) {
412 } 397 }
413 398
414 P2PSocketHost::~P2PSocketHost() { } 399 P2PSocketHost::~P2PSocketHost() { }
415 400
416 // Verifies that the packet |data| has a valid STUN header. 401 // Verifies that the packet |data| has a valid STUN header.
417 // static 402 // static
418 bool P2PSocketHost::GetStunPacketType( 403 bool P2PSocketHost::GetStunPacketType(
419 const char* data, int data_size, StunMessageType* type) { 404 const char* data, int data_size, StunMessageType* type) {
420 405
421 if (data_size < kStunHeaderSize) 406 if (data_size < kStunHeaderSize)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 } 439 }
455 } 440 }
456 441
457 // static 442 // static
458 bool P2PSocketHost::IsRequestOrResponse(StunMessageType type) { 443 bool P2PSocketHost::IsRequestOrResponse(StunMessageType type) {
459 return type == STUN_BINDING_REQUEST || type == STUN_BINDING_RESPONSE || 444 return type == STUN_BINDING_REQUEST || type == STUN_BINDING_RESPONSE ||
460 type == STUN_ALLOCATE_REQUEST || type == STUN_ALLOCATE_RESPONSE; 445 type == STUN_ALLOCATE_REQUEST || type == STUN_ALLOCATE_RESPONSE;
461 } 446 }
462 447
463 // static 448 // static
464 P2PSocketHost* P2PSocketHost::Create(IPC::Sender* message_sender, 449 P2PSocketHost* P2PSocketHost::Create(
465 int socket_id, 450 IPC::Sender* message_sender, int id, P2PSocketType type,
466 P2PSocketType type, 451 net::URLRequestContextGetter* url_context,
467 net::URLRequestContextGetter* url_context, 452 P2PMessageThrottler* throttler) {
468 P2PMessageThrottler* throttler) {
469 switch (type) { 453 switch (type) {
470 case P2P_SOCKET_UDP: 454 case P2P_SOCKET_UDP:
471 return new P2PSocketHostUdp(message_sender, socket_id, throttler); 455 return new P2PSocketHostUdp(message_sender, id, throttler);
472 case P2P_SOCKET_TCP_SERVER: 456 case P2P_SOCKET_TCP_SERVER:
473 return new P2PSocketHostTcpServer( 457 return new P2PSocketHostTcpServer(
474 message_sender, socket_id, P2P_SOCKET_TCP_CLIENT); 458 message_sender, id, P2P_SOCKET_TCP_CLIENT);
475 459
476 case P2P_SOCKET_STUN_TCP_SERVER: 460 case P2P_SOCKET_STUN_TCP_SERVER:
477 return new P2PSocketHostTcpServer( 461 return new P2PSocketHostTcpServer(
478 message_sender, socket_id, P2P_SOCKET_STUN_TCP_CLIENT); 462 message_sender, id, P2P_SOCKET_STUN_TCP_CLIENT);
479 463
480 case P2P_SOCKET_TCP_CLIENT: 464 case P2P_SOCKET_TCP_CLIENT:
481 case P2P_SOCKET_SSLTCP_CLIENT: 465 case P2P_SOCKET_SSLTCP_CLIENT:
482 case P2P_SOCKET_TLS_CLIENT: 466 case P2P_SOCKET_TLS_CLIENT:
483 return new P2PSocketHostTcp(message_sender, socket_id, type, url_context); 467 return new P2PSocketHostTcp(message_sender, id, type, url_context);
484 468
485 case P2P_SOCKET_STUN_TCP_CLIENT: 469 case P2P_SOCKET_STUN_TCP_CLIENT:
486 case P2P_SOCKET_STUN_SSLTCP_CLIENT: 470 case P2P_SOCKET_STUN_SSLTCP_CLIENT:
487 case P2P_SOCKET_STUN_TLS_CLIENT: 471 case P2P_SOCKET_STUN_TLS_CLIENT:
488 return new P2PSocketHostStunTcp( 472 return new P2PSocketHostStunTcp(message_sender, id, type, url_context);
489 message_sender, socket_id, type, url_context);
490 } 473 }
491 474
492 NOTREACHED(); 475 NOTREACHED();
493 return NULL; 476 return NULL;
494 } 477 }
495 478
496 void P2PSocketHost::StartRtpDump(
497 bool incoming,
498 bool outgoing,
499 const RenderProcessHost::WebRtcRtpPacketCallback& packet_callback) {
500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
501 DCHECK(!packet_callback.is_null());
502 DCHECK(incoming || outgoing);
503
504 if (incoming)
505 dump_incoming_rtp_packet_ = true;
506
507 if (outgoing)
508 dump_outgoing_rtp_packet_ = true;
509
510 packet_dump_callback_ = packet_callback;
511 }
512
513 void P2PSocketHost::StopRtpDump(bool incoming, bool outgoing) {
514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
515 DCHECK(incoming || outgoing);
516
517 if (incoming)
518 dump_incoming_rtp_packet_ = false;
519
520 if (outgoing)
521 dump_outgoing_rtp_packet_ = false;
522
523 if (!dump_incoming_rtp_packet_ && !dump_outgoing_rtp_packet_)
524 packet_dump_callback_.Reset();
525 }
526
527 void P2PSocketHost::DumpRtpPacket(const char* packet,
528 size_t length,
529 bool incoming) {
530 if (IsDtlsPacket(packet, length) || IsRtcpPacket(packet))
531 return;
532
533 int rtp_packet_pos = 0;
534 int rtp_packet_length = length;
535 if (!packet_processing_helpers::GetRtpPacketStartPositionAndLength(
536 packet, length, &rtp_packet_pos, &rtp_packet_length))
537 return;
538
539 packet += rtp_packet_pos;
540
541 size_t header_length = 0;
542 bool valid = ValidateRtpHeader(packet, rtp_packet_length, &header_length);
543 if (!valid) {
544 DCHECK(false);
545 return;
546 }
547
548 scoped_ptr<uint8[]> header_buffer(new uint8[header_length]);
549 memcpy(header_buffer.get(), packet, header_length);
550
551 // Posts to the IO thread as the data members should be accessed on the IO
552 // thread only.
553 BrowserThread::PostTask(BrowserThread::IO,
554 FROM_HERE,
555 base::Bind(&P2PSocketHost::DumpRtpPacketOnIOThread,
556 weak_ptr_factory_.GetWeakPtr(),
557 Passed(&header_buffer),
558 header_length,
559 rtp_packet_length,
560 incoming));
561 }
562
563 void P2PSocketHost::DumpRtpPacketOnIOThread(scoped_ptr<uint8[]> packet_header,
564 size_t header_length,
565 size_t packet_length,
566 bool incoming) {
567 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
568
569 if ((incoming && !dump_incoming_rtp_packet_) ||
570 (!incoming && !dump_outgoing_rtp_packet_) ||
571 packet_dump_callback_.is_null()) {
572 return;
573 }
574
575 // |packet_dump_callback_| must be called on the UI thread.
576 BrowserThread::PostTask(BrowserThread::UI,
577 FROM_HERE,
578 base::Bind(packet_dump_callback_,
579 packet_header.get(),
580 header_length,
581 packet_length,
582 incoming));
583 }
584
585 } // namespace content 479 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698