Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / p2p / socket_host_udp.cc
index 921eac8..3833b62 100644 (file)
@@ -5,16 +5,17 @@
 #include "content/browser/renderer_host/p2p/socket_host_udp.h"
 
 #include "base/bind.h"
-#include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/stl_util.h"
 #include "content/browser/renderer_host/p2p/socket_host_throttler.h"
 #include "content/common/p2p_messages.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/content_client.h"
 #include "ipc/ipc_sender.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_util.h"
+#include "third_party/webrtc/base/asyncpacketsocket.h"
 
 namespace {
 
@@ -40,12 +41,8 @@ bool IsTransientError(int error) {
          error == net::ERR_ADDRESS_INVALID ||
          error == net::ERR_ACCESS_DENIED ||
          error == net::ERR_CONNECTION_RESET ||
-         error == net::ERR_OUT_OF_MEMORY;
-}
-
-bool AllowUDPWithoutSTUN() {
-  return CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kDisableP2PSocketSTUNFilter);
+         error == net::ERR_OUT_OF_MEMORY ||
+         error == net::ERR_INTERNET_DISCONNECTED;
 }
 
 }  // namespace
@@ -55,12 +52,12 @@ namespace content {
 P2PSocketHostUdp::PendingPacket::PendingPacket(
     const net::IPEndPoint& to,
     const std::vector<char>& content,
-    net::DiffServCodePoint dscp_,
+    const rtc::PacketOptions& options,
     uint64 id)
     : to(to),
       data(new net::IOBuffer(content.size())),
       size(content.size()),
-      dscp(dscp_),
+      packet_options(options),
       id(id) {
   memcpy(data->data(), &content[0], size);
 }
@@ -69,10 +66,12 @@ P2PSocketHostUdp::PendingPacket::~PendingPacket() {
 }
 
 P2PSocketHostUdp::P2PSocketHostUdp(IPC::Sender* message_sender,
-                                   int id,
+                                   int socket_id,
                                    P2PMessageThrottler* throttler)
-    : P2PSocketHost(message_sender, id),
-      socket_(new net::UDPServerSocket(NULL, net::NetLog::Source())),
+    : P2PSocketHost(message_sender, socket_id),
+      socket_(
+          new net::UDPServerSocket(GetContentClient()->browser()->GetNetLog(),
+                                   net::NetLog::Source())),
       send_pending_(false),
       last_dscp_(net::DSCP_CS0),
       throttler_(throttler) {
@@ -86,7 +85,7 @@ P2PSocketHostUdp::~P2PSocketHostUdp() {
 }
 
 bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address,
-                            const net::IPEndPoint& remote_address) {
+                            const P2PHostAndIPEndPoint& remote_address) {
   DCHECK_EQ(state_, STATE_UNINITIALIZED);
 
   int result = socket_->Listen(local_address);
@@ -97,7 +96,7 @@ bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address,
   }
 
   // Setting recv socket buffer size.
-  if (!socket_->SetReceiveBufferSize(kRecvSocketBufferSize)) {
+  if (socket_->SetReceiveBufferSize(kRecvSocketBufferSize) != net::OK) {
     LOG(WARNING) << "Failed to set socket receive buffer size to "
                  << kRecvSocketBufferSize;
   }
@@ -114,7 +113,9 @@ bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address,
 
   state_ = STATE_OPEN;
 
-  message_sender_->Send(new P2PMsg_OnSocketCreated(id_, address));
+  // NOTE: Remote address will be same as what renderer provided.
+  message_sender_->Send(new P2PMsg_OnSocketCreated(
+      id_, address, remote_address.ip_address));
 
   recv_buffer_ = new net::IOBuffer(kReadBufferSize);
   DoRead();
@@ -162,7 +163,7 @@ void P2PSocketHostUdp::HandleReadResult(int result) {
     if (!ContainsKey(connected_peers_, recv_address_)) {
       P2PSocketHost::StunMessageType type;
       bool stun = GetStunPacketType(&*data.begin(), data.size(), &type);
-      if ((stun && IsRequestOrResponse(type)) || AllowUDPWithoutSTUN()) {
+      if ((stun && IsRequestOrResponse(type))) {
         connected_peers_.insert(recv_address_);
       } else if (!stun || type == STUN_DATA_INDICATION) {
         LOG(ERROR) << "Received unexpected data packet from "
@@ -174,6 +175,9 @@ void P2PSocketHostUdp::HandleReadResult(int result) {
 
     message_sender_->Send(new P2PMsg_OnDataReceived(
         id_, recv_address_, data, base::TimeTicks::Now()));
+
+    if (dump_incoming_rtp_packet_)
+      DumpRtpPacket(&data[0], data.size(), true);
   } else if (result < 0 && !IsTransientError(result)) {
     LOG(ERROR) << "Error when reading from UDP socket: " << result;
     OnError();
@@ -182,7 +186,7 @@ void P2PSocketHostUdp::HandleReadResult(int result) {
 
 void P2PSocketHostUdp::Send(const net::IPEndPoint& to,
                             const std::vector<char>& data,
-                            net::DiffServCodePoint dscp,
+                            const rtc::PacketOptions& options,
                             uint64 packet_id) {
   if (!socket_) {
     // The Send message may be sent after the an OnError message was
@@ -190,7 +194,7 @@ void P2PSocketHostUdp::Send(const net::IPEndPoint& to,
     return;
   }
 
-  if (!ContainsKey(connected_peers_, to) && !AllowUDPWithoutSTUN()) {
+  if (!ContainsKey(connected_peers_, to)) {
     P2PSocketHost::StunMessageType type = P2PSocketHost::StunMessageType();
     bool stun = GetStunPacketType(&*data.begin(), data.size(), &type);
     if (!stun || type == STUN_DATA_INDICATION) {
@@ -208,9 +212,10 @@ void P2PSocketHostUdp::Send(const net::IPEndPoint& to,
   }
 
   if (send_pending_) {
-    send_queue_.push_back(PendingPacket(to, data, dscp, packet_id));
+    send_queue_.push_back(PendingPacket(to, data, options, packet_id));
   } else {
-    PendingPacket packet(to, data, dscp, packet_id);
+    // TODO(mallinath: Remove unnecessary memcpy in this case.
+    PendingPacket packet(to, data, options, packet_id);
     DoSend(packet);
   }
 }
@@ -222,11 +227,13 @@ void P2PSocketHostUdp::DoSend(const PendingPacket& packet) {
   // 1. If the outgoing packet is set to DSCP_NO_CHANGE
   // 2. If no change in DSCP value from last packet
   // 3. If there is any error in setting DSCP on socket.
-  if (packet.dscp != net::DSCP_NO_CHANGE &&
-      last_dscp_ != packet.dscp && last_dscp_ != net::DSCP_NO_CHANGE) {
-    int result = socket_->SetDiffServCodePoint(packet.dscp);
+  net::DiffServCodePoint dscp =
+      static_cast<net::DiffServCodePoint>(packet.packet_options.dscp);
+  if (dscp != net::DSCP_NO_CHANGE && last_dscp_ != dscp &&
+      last_dscp_ != net::DSCP_NO_CHANGE) {
+    int result = socket_->SetDiffServCodePoint(dscp);
     if (result == net::OK) {
-      last_dscp_ = packet.dscp;
+      last_dscp_ = dscp;
     } else if (!IsTransientError(result) && last_dscp_ != net::DSCP_CS0) {
       // We receieved a non-transient error, and it seems we have
       // not changed the DSCP in the past, disable DSCP as it unlikely
@@ -234,6 +241,8 @@ void P2PSocketHostUdp::DoSend(const PendingPacket& packet) {
       last_dscp_ = net::DSCP_NO_CHANGE;
     }
   }
+  packet_processing_helpers::ApplyPacketOptions(
+      packet.data->data(), packet.size, packet.packet_options, 0);
   int result = socket_->SendTo(
       packet.data.get(),
       packet.size,
@@ -257,6 +266,9 @@ void P2PSocketHostUdp::DoSend(const PendingPacket& packet) {
   } else {
     HandleSendResult(packet.id, result);
   }
+
+  if (dump_outgoing_rtp_packet_)
+    DumpRtpPacket(packet.data->data(), packet.size, false);
 }
 
 void P2PSocketHostUdp::OnSend(uint64 packet_id, int result) {
@@ -277,15 +289,16 @@ void P2PSocketHostUdp::OnSend(uint64 packet_id, int result) {
 void P2PSocketHostUdp::HandleSendResult(uint64 packet_id, int result) {
   TRACE_EVENT_ASYNC_END1("p2p", "Send", packet_id,
                          "result", result);
-  if (result > 0) {
-    message_sender_->Send(new P2PMsg_OnSendComplete(id_));
-  } else if (IsTransientError(result)) {
+  if (result < 0) {
+    if (!IsTransientError(result)) {
+      LOG(ERROR) << "Error when sending data in UDP socket: " << result;
+      OnError();
+      return;
+    }
     VLOG(0) << "sendto() has failed twice returning a "
-        " transient error. Dropping the packet.";
-  } else if (result < 0) {
-    LOG(ERROR) << "Error when sending data in UDP socket: " << result;
-    OnError();
+               " transient error. Dropping the packet.";
   }
+  message_sender_->Send(new P2PMsg_OnSendComplete(id_));
 }
 
 P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection(
@@ -299,9 +312,9 @@ bool P2PSocketHostUdp::SetOption(P2PSocketOption option, int value) {
   DCHECK_EQ(STATE_OPEN, state_);
   switch (option) {
     case P2P_SOCKET_OPT_RCVBUF:
-      return socket_->SetReceiveBufferSize(value);
+      return socket_->SetReceiveBufferSize(value) == net::OK;
     case P2P_SOCKET_OPT_SNDBUF:
-      return socket_->SetSendBufferSize(value);
+      return socket_->SetSendBufferSize(value) == net::OK;
     case P2P_SOCKET_OPT_DSCP:
       return (net::OK == socket_->SetDiffServCodePoint(
           static_cast<net::DiffServCodePoint>(value))) ? true : false;