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

Side by Side Diff: content/browser/renderer_host/p2p/socket_host_udp.cc

Issue 13584008: Send notification about outgoing p2p packets from browser to renderer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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_udp.h" 5 #include "content/browser/renderer_host/p2p/socket_host_udp.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "content/common/p2p_messages.h" 8 #include "content/common/p2p_messages.h"
9 #include "ipc/ipc_sender.h" 9 #include "ipc/ipc_sender.h"
10 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
(...skipping 24 matching lines...) Expand all
35 size(content.size()) { 35 size(content.size()) {
36 memcpy(data->data(), &content[0], size); 36 memcpy(data->data(), &content[0], size);
37 } 37 }
38 38
39 P2PSocketHostUdp::PendingPacket::~PendingPacket() { 39 P2PSocketHostUdp::PendingPacket::~PendingPacket() {
40 } 40 }
41 41
42 P2PSocketHostUdp::P2PSocketHostUdp(IPC::Sender* message_sender, int id) 42 P2PSocketHostUdp::P2PSocketHostUdp(IPC::Sender* message_sender, int id)
43 : P2PSocketHost(message_sender, id), 43 : P2PSocketHost(message_sender, id),
44 socket_(new net::UDPServerSocket(NULL, net::NetLog::Source())), 44 socket_(new net::UDPServerSocket(NULL, net::NetLog::Source())),
45 send_queue_bytes_(0),
46 send_pending_(false) { 45 send_pending_(false) {
47 } 46 }
48 47
49 P2PSocketHostUdp::~P2PSocketHostUdp() { 48 P2PSocketHostUdp::~P2PSocketHostUdp() {
50 if (state_ == STATE_OPEN) { 49 if (state_ == STATE_OPEN) {
51 DCHECK(socket_.get()); 50 DCHECK(socket_.get());
52 socket_.reset(); 51 socket_.reset();
53 } 52 }
54 } 53 }
55 54
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 } 94 }
96 95
97 void P2PSocketHostUdp::DoRead() { 96 void P2PSocketHostUdp::DoRead() {
98 int result; 97 int result;
99 do { 98 do {
100 result = socket_->RecvFrom(recv_buffer_, kReadBufferSize, &recv_address_, 99 result = socket_->RecvFrom(recv_buffer_, kReadBufferSize, &recv_address_,
101 base::Bind(&P2PSocketHostUdp::OnRecv, 100 base::Bind(&P2PSocketHostUdp::OnRecv,
102 base::Unretained(this))); 101 base::Unretained(this)));
103 if (result == net::ERR_IO_PENDING) 102 if (result == net::ERR_IO_PENDING)
104 return; 103 return;
105 DidCompleteRead(result); 104 HandleReadResult(result);
106 } while (state_ == STATE_OPEN); 105 } while (state_ == STATE_OPEN);
107 } 106 }
108 107
109 void P2PSocketHostUdp::OnRecv(int result) { 108 void P2PSocketHostUdp::OnRecv(int result) {
110 DidCompleteRead(result); 109 HandleReadResult(result);
111 if (state_ == STATE_OPEN) { 110 if (state_ == STATE_OPEN) {
112 DoRead(); 111 DoRead();
113 } 112 }
114 } 113 }
115 114
116 void P2PSocketHostUdp::DidCompleteRead(int result) { 115 void P2PSocketHostUdp::HandleReadResult(int result) {
117 DCHECK_EQ(state_, STATE_OPEN); 116 DCHECK_EQ(state_, STATE_OPEN);
118 117
119 if (result > 0) { 118 if (result > 0) {
120 std::vector<char> data(recv_buffer_->data(), recv_buffer_->data() + result); 119 std::vector<char> data(recv_buffer_->data(), recv_buffer_->data() + result);
121 120
122 if (connected_peers_.find(recv_address_) == connected_peers_.end()) { 121 if (connected_peers_.find(recv_address_) == connected_peers_.end()) {
123 P2PSocketHost::StunMessageType type; 122 P2PSocketHost::StunMessageType type;
124 bool stun = GetStunPacketType(&*data.begin(), data.size(), &type); 123 bool stun = GetStunPacketType(&*data.begin(), data.size(), &type);
125 if (stun && IsRequestOrResponse(type)) { 124 if (stun && IsRequestOrResponse(type)) {
126 connected_peers_.insert(recv_address_); 125 connected_peers_.insert(recv_address_);
(...skipping 25 matching lines...) Expand all
152 bool stun = GetStunPacketType(&*data.begin(), data.size(), &type); 151 bool stun = GetStunPacketType(&*data.begin(), data.size(), &type);
153 if (!stun || type == STUN_DATA_INDICATION) { 152 if (!stun || type == STUN_DATA_INDICATION) {
154 LOG(ERROR) << "Page tried to send a data packet to " << to.ToString() 153 LOG(ERROR) << "Page tried to send a data packet to " << to.ToString()
155 << " before STUN binding is finished."; 154 << " before STUN binding is finished.";
156 OnError(); 155 OnError();
157 return; 156 return;
158 } 157 }
159 } 158 }
160 159
161 if (send_pending_) { 160 if (send_pending_) {
162 if (send_queue_bytes_ + static_cast<int>(data.size()) >
163 kMaxSendBufferSize) {
164 LOG(WARNING) << "Send buffer is full. Dropping a packet.";
165 return;
166 }
167 send_queue_.push_back(PendingPacket(to, data)); 161 send_queue_.push_back(PendingPacket(to, data));
168 send_queue_bytes_ += data.size();
169 } else { 162 } else {
170 PendingPacket packet(to, data); 163 PendingPacket packet(to, data);
171 DoSend(packet); 164 DoSend(packet);
172 } 165 }
173 } 166 }
174 167
175 void P2PSocketHostUdp::DoSend(const PendingPacket& packet) { 168 void P2PSocketHostUdp::DoSend(const PendingPacket& packet) {
176 int result = socket_->SendTo(packet.data, packet.size, packet.to, 169 int result = socket_->SendTo(packet.data, packet.size, packet.to,
177 base::Bind(&P2PSocketHostUdp::OnSend, 170 base::Bind(&P2PSocketHostUdp::OnSend,
178 base::Unretained(this))); 171 base::Unretained(this)));
179 172
180 // sendto() may return an error, e.g. if we've received an ICMP Destination 173 // sendto() may return an error, e.g. if we've received an ICMP Destination
181 // Unreachable message. When this happens try sending the same packet again, 174 // Unreachable message. When this happens try sending the same packet again,
182 // and just drop it if it fails again. 175 // and just drop it if it fails again.
183 if (IsTransientError(result)) { 176 if (IsTransientError(result)) {
184 result = socket_->SendTo(packet.data, packet.size, packet.to, 177 result = socket_->SendTo(packet.data, packet.size, packet.to,
185 base::Bind(&P2PSocketHostUdp::OnSend, 178 base::Bind(&P2PSocketHostUdp::OnSend,
186 base::Unretained(this))); 179 base::Unretained(this)));
187 } 180 }
188 181
189 if (result == net::ERR_IO_PENDING) { 182 if (result == net::ERR_IO_PENDING) {
190 send_pending_ = true; 183 send_pending_ = true;
191 } else if (IsTransientError(result)) { 184 } else {
192 LOG(INFO) << "sendto() has failed twice returning a " 185 HandleSendResult(result);
193 " transient error. Dropping the packet.";
194 } else if (result < 0) {
195 LOG(ERROR) << "Error when sending data in UDP socket: " << result;
196 OnError();
197 } 186 }
198 } 187 }
199 188
200 void P2PSocketHostUdp::OnSend(int result) { 189 void P2PSocketHostUdp::OnSend(int result) {
201 DCHECK(send_pending_); 190 DCHECK(send_pending_);
202 DCHECK_NE(result, net::ERR_IO_PENDING); 191 DCHECK_NE(result, net::ERR_IO_PENDING);
203 192
204 send_pending_ = false; 193 send_pending_ = false;
205 194
206 if (result < 0 && !IsTransientError(result)) { 195 HandleSendResult(result);
207 OnError();
208 return;
209 }
210 196
211 // Send next packets if we have them waiting in the buffer. 197 // Send next packets if we have them waiting in the buffer.
212 while (!send_queue_.empty() && !send_pending_) { 198 while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) {
213 DoSend(send_queue_.front()); 199 DoSend(send_queue_.front());
214 send_queue_bytes_ -= send_queue_.front().size;
215 send_queue_.pop_front(); 200 send_queue_.pop_front();
216 } 201 }
217 } 202 }
218 203
204 void P2PSocketHostUdp::HandleSendResult(int result) {
205 if (result > 0) {
206 message_sender_->Send(new P2PMsg_OnSendComplete(id_));
207 } else if (IsTransientError(result)) {
208 LOG(INFO) << "sendto() has failed twice returning a "
209 " transient error. Dropping the packet.";
210 } else if (result < 0) {
211 LOG(ERROR) << "Error when sending data in UDP socket: " << result;
212 OnError();
213 }
214 }
215
219 P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection( 216 P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection(
220 const net::IPEndPoint& remote_address, int id) { 217 const net::IPEndPoint& remote_address, int id) {
221 NOTREACHED(); 218 NOTREACHED();
222 OnError(); 219 OnError();
223 return NULL; 220 return NULL;
224 } 221 }
225 222
226 } // namespace content 223 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698