diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-24 01:21:39 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-24 01:21:39 +0000 |
commit | 0b8ad4ac6be670d998dae46de2048d1de83e6554 (patch) | |
tree | b9c081e4c73802bd89b882e57421aebfa67d9c94 /content/browser/renderer_host/p2p | |
parent | a5018fc5bc3d48e93acdfed290d6f4d46ea0a688 (diff) | |
download | chromium_src-0b8ad4ac6be670d998dae46de2048d1de83e6554.zip chromium_src-0b8ad4ac6be670d998dae46de2048d1de83e6554.tar.gz chromium_src-0b8ad4ac6be670d998dae46de2048d1de83e6554.tar.bz2 |
Fix P2PSocketHostUDP to handle EHOSTUNREACH error.
Previous fix for this bug wasn't complete, as it didn't cover the case
when the error is returned synchronously.
BUG=133624
Review URL: https://chromiumcodereview.appspot.com/11943017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@178456 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/renderer_host/p2p')
-rw-r--r-- | content/browser/renderer_host/p2p/socket_host_udp.cc | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.cc b/content/browser/renderer_host/p2p/socket_host_udp.cc index 0022629..226a278 100644 --- a/content/browser/renderer_host/p2p/socket_host_udp.cc +++ b/content/browser/renderer_host/p2p/socket_host_udp.cc @@ -16,6 +16,13 @@ namespace { // UDP packets cannot be bigger than 64k. const int kReadBufferSize = 65536; +// Defines set of transient errors. These errors are ignored when we get them +// from sendto() calls. +bool IsTransientError(int error) { + return error == net::ERR_ADDRESS_UNREACHABLE || + error == net::ERR_ADDRESS_INVALID; +} + } // namespace namespace content { @@ -92,8 +99,10 @@ void P2PSocketHostUdp::DoRead() { result = socket_->RecvFrom(recv_buffer_, kReadBufferSize, &recv_address_, base::Bind(&P2PSocketHostUdp::OnRecv, base::Unretained(this))); + if (result == net::ERR_IO_PENDING) + return; DidCompleteRead(result); - } while (result > 0); + } while (state_ == STATE_OPEN); } void P2PSocketHostUdp::OnRecv(int result) { @@ -123,7 +132,7 @@ void P2PSocketHostUdp::DidCompleteRead(int result) { } message_sender_->Send(new P2PMsg_OnDataReceived(id_, recv_address_, data)); - } else if (result < 0 && result != net::ERR_IO_PENDING) { + } else if (result < 0 && !IsTransientError(result)) { LOG(ERROR) << "Error when reading from UDP socket: " << result; OnError(); } @@ -166,8 +175,21 @@ void P2PSocketHostUdp::DoSend(const PendingPacket& packet) { int result = socket_->SendTo(packet.data, packet.size, packet.to, base::Bind(&P2PSocketHostUdp::OnSend, base::Unretained(this))); + + // sendto() may return an error, e.g. if we've received an ICMP Destination + // Unreachable message. When this happens try sending the same packet again, + // and just drop it if it fails again. + if (IsTransientError(result)) { + result = socket_->SendTo(packet.data, packet.size, packet.to, + base::Bind(&P2PSocketHostUdp::OnSend, + base::Unretained(this))); + } + if (result == net::ERR_IO_PENDING) { send_pending_ = true; + } else if (IsTransientError(result)) { + LOG(INFO) << "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(); @@ -180,11 +202,7 @@ void P2PSocketHostUdp::OnSend(int result) { send_pending_ = false; - // We may get ERR_ADDRESS_UNREACHABLE here if the peer host has a - // local IP address with the same subnet address as the local - // host. This error is ingored so that this socket can still be used - // to try to connect to different candidates. - if (result < 0 && result != net::ERR_ADDRESS_UNREACHABLE) { + if (result < 0 && !IsTransientError(result)) { OnError(); return; } |