Chromium Code Reviews| Index: content/browser/renderer_host/p2p/socket_host.cc |
| diff --git a/content/browser/renderer_host/p2p/socket_host.cc b/content/browser/renderer_host/p2p/socket_host.cc |
| index 3422322dbe1f9c31f717923c2e414ec4235adf40..46ca5228f5061acf769f8bdf62865db2f04d5bbc 100644 |
| --- a/content/browser/renderer_host/p2p/socket_host.cc |
| +++ b/content/browser/renderer_host/p2p/socket_host.cc |
| @@ -8,6 +8,8 @@ |
| #include "content/browser/renderer_host/p2p/socket_host_tcp.h" |
| #include "content/browser/renderer_host/p2p/socket_host_tcp_server.h" |
| #include "content/browser/renderer_host/p2p/socket_host_udp.h" |
| +#include "content/browser/renderer_host/render_process_host_impl.h" |
| +#include "content/public/browser/browser_thread.h" |
| #include "crypto/hmac.h" |
| #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" |
| #include "third_party/libjingle/source/talk/base/byteorder.h" |
| @@ -55,7 +57,7 @@ bool IsRtpPacket(const char* data, int len) { |
| } |
| // Verifies rtp header and message length. |
| -bool ValidateRtpHeader(char* rtp, int length) { |
| +bool ValidateRtpHeader(const char* rtp, int length, size_t* header_length) { |
| int cc_count = rtp[0] & 0x0F; |
| int rtp_hdr_len_without_extn = kMinRtpHdrLen + 4 * cc_count; |
| if (rtp_hdr_len_without_extn > length) { |
| @@ -65,6 +67,9 @@ bool ValidateRtpHeader(char* rtp, int length) { |
| // If extension bit is not set, we are done with header processing, as input |
| // length is verified above. |
| if (!(rtp[0] & 0x10)) { |
| + if (header_length) |
| + *header_length = rtp_hdr_len_without_extn; |
| + |
| return true; |
| } |
| @@ -78,6 +83,9 @@ bool ValidateRtpHeader(char* rtp, int length) { |
| if (rtp_hdr_len_without_extn + kRtpExtnHdrLen + extn_length > length) { |
| return false; |
| } |
| + |
| + if (header_length) |
| + *header_length = rtp_hdr_len_without_extn + kRtpExtnHdrLen + extn_length; |
| return true; |
| } |
| @@ -206,8 +214,10 @@ bool ApplyPacketOptions(char* data, int length, |
| return true; |
| } |
| -bool GetRtpPacketStartPositionAndLength( |
| - char* packet, int length, int* rtp_start_pos, int* rtp_packet_length) { |
| +bool GetRtpPacketStartPositionAndLength(const char* packet, |
| + int length, |
| + int* rtp_start_pos, |
| + int* rtp_packet_length) { |
| int rtp_begin, rtp_length; |
| if (IsTurnChannelData(packet)) { |
| // Turn Channel Message header format. |
| @@ -243,7 +253,7 @@ bool GetRtpPacketStartPositionAndLength( |
| // First skip mandatory stun header which is of 20 bytes. |
| rtp_begin = P2PSocketHost::kStunHeaderSize; |
| // Loop through STUN attributes until we find STUN DATA attribute. |
| - char* start = packet + rtp_begin; |
| + const char* start = packet + rtp_begin; |
| bool data_attr_present = false; |
| while ((packet + rtp_begin) - start < stun_msg_len) { |
| // Keep reading STUN attributes until we hit DATA attribute. |
| @@ -303,7 +313,7 @@ bool GetRtpPacketStartPositionAndLength( |
| // Making sure we have a valid RTP packet at the end. |
| if (!(rtp_length < kMinRtpHdrLen) && |
| IsRtpPacket(packet + rtp_begin, rtp_length) && |
| - ValidateRtpHeader(packet + rtp_begin, rtp_length)) { |
| + ValidateRtpHeader(packet + rtp_begin, rtp_length, NULL)) { |
| *rtp_start_pos = rtp_begin; |
| *rtp_packet_length = rtp_length; |
| return true; |
| @@ -390,10 +400,14 @@ bool UpdateRtpAbsSendTimeExtn(char* rtp, int length, |
| } // packet_processing_helpers |
| P2PSocketHost::P2PSocketHost(IPC::Sender* message_sender, |
| - int id) |
| + int socket_id, |
| + int render_process_host_id) |
| : message_sender_(message_sender), |
| - id_(id), |
| - state_(STATE_UNINITIALIZED) { |
| + id_(socket_id), |
| + render_process_host_id_(render_process_host_id), |
| + state_(STATE_UNINITIALIZED), |
| + dump_incoming_rtp_packet_(false), |
| + dump_outgoing_rtp_packet_(false) { |
| } |
| P2PSocketHost::~P2PSocketHost() { } |
| @@ -446,34 +460,106 @@ bool P2PSocketHost::IsRequestOrResponse(StunMessageType type) { |
| } |
| // static |
| -P2PSocketHost* P2PSocketHost::Create( |
| - IPC::Sender* message_sender, int id, P2PSocketType type, |
| - net::URLRequestContextGetter* url_context, |
| - P2PMessageThrottler* throttler) { |
| +P2PSocketHost* P2PSocketHost::Create(IPC::Sender* message_sender, |
| + int socket_id, |
| + int render_process_host_id, |
| + P2PSocketType type, |
| + net::URLRequestContextGetter* url_context, |
| + P2PMessageThrottler* throttler) { |
| switch (type) { |
| case P2P_SOCKET_UDP: |
| - return new P2PSocketHostUdp(message_sender, id, throttler); |
| + return new P2PSocketHostUdp( |
| + message_sender, socket_id, render_process_host_id, throttler); |
| case P2P_SOCKET_TCP_SERVER: |
| - return new P2PSocketHostTcpServer( |
| - message_sender, id, P2P_SOCKET_TCP_CLIENT); |
| + return new P2PSocketHostTcpServer(message_sender, |
| + socket_id, |
| + render_process_host_id, |
| + P2P_SOCKET_TCP_CLIENT); |
| case P2P_SOCKET_STUN_TCP_SERVER: |
| - return new P2PSocketHostTcpServer( |
| - message_sender, id, P2P_SOCKET_STUN_TCP_CLIENT); |
| + return new P2PSocketHostTcpServer(message_sender, |
| + socket_id, |
| + render_process_host_id, |
| + P2P_SOCKET_STUN_TCP_CLIENT); |
| case P2P_SOCKET_TCP_CLIENT: |
| case P2P_SOCKET_SSLTCP_CLIENT: |
| case P2P_SOCKET_TLS_CLIENT: |
| - return new P2PSocketHostTcp(message_sender, id, type, url_context); |
| + return new P2PSocketHostTcp( |
| + message_sender, socket_id, render_process_host_id, type, url_context); |
| case P2P_SOCKET_STUN_TCP_CLIENT: |
| case P2P_SOCKET_STUN_SSLTCP_CLIENT: |
| case P2P_SOCKET_STUN_TLS_CLIENT: |
| - return new P2PSocketHostStunTcp(message_sender, id, type, url_context); |
| + return new P2PSocketHostStunTcp( |
| + message_sender, socket_id, render_process_host_id, type, url_context); |
| } |
| NOTREACHED(); |
| return NULL; |
| } |
| +void P2PSocketHost::StartRtpDump(bool incoming, bool outgoing) { |
| + dump_incoming_rtp_packet_ = incoming; |
| + dump_outgoing_rtp_packet_ = outgoing; |
| +} |
| + |
| +void P2PSocketHost::StopRtpDump(bool incoming, bool outgoing) { |
| + dump_incoming_rtp_packet_ = !incoming; |
| + dump_outgoing_rtp_packet_ = !outgoing; |
| +} |
| + |
| +// static |
| +void P2PSocketHost::DumpRtpPacketOnUIThread(scoped_ptr<char[]> packet_header, |
| + size_t header_length, |
| + size_t packet_length, |
| + bool incoming, |
| + int render_process_host_id) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + |
| + content::RenderProcessHostImpl* render_process_host_impl = |
| + static_cast<content::RenderProcessHostImpl*>( |
| + content::RenderProcessHost::FromID(render_process_host_id)); |
| + |
| + if (render_process_host_impl) { |
| + render_process_host_impl->OnRtpPacket( |
| + reinterpret_cast<const uint8*>(packet_header.get()), |
| + header_length, |
| + packet_length, |
| + incoming); |
| + } |
| +} |
| + |
| +void P2PSocketHost::DumpRtpPacket(const char* packet, |
| + size_t length, |
| + bool incoming) { |
| + if (IsDtlsPacket(packet, length) || IsRtcpPacket(packet)) |
| + return; |
| + |
| + int rtp_packet_pos = 0; |
| + int rtp_packet_length = length; |
| + if (!packet_processing_helpers::GetRtpPacketStartPositionAndLength( |
| + packet, length, &rtp_packet_pos, &rtp_packet_length)) |
| + return; |
| + |
| + packet += rtp_packet_pos; |
| + |
| + size_t header_length = 0; |
| + bool valid = ValidateRtpHeader(packet, rtp_packet_length, &header_length); |
| + if (!valid) |
| + return; |
|
Mallinath (Gone from Chromium)
2014/05/14 00:57:01
add a DCHECK before returning.
jiayl
2014/05/14 18:59:12
Done.
|
| + |
| + scoped_ptr<char[]> header_copy(new char[header_length]); |
| + memcpy(header_copy.get(), packet, header_length); |
| + |
| + BrowserThread::PostTask(BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(&P2PSocketHost::DumpRtpPacketOnUIThread, |
| + base::Passed(&header_copy), |
| + header_length, |
| + length, |
| + incoming, |
| + render_process_host_id_)); |
| +} |
| + |
| } // namespace content |