OLD | NEW |
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 "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "content/browser/renderer_host/p2p/socket_host_throttler.h" | 10 #include "content/browser/renderer_host/p2p/socket_host_throttler.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 error == net::ERR_OUT_OF_MEMORY; | 43 error == net::ERR_OUT_OF_MEMORY; |
44 } | 44 } |
45 | 45 |
46 } // namespace | 46 } // namespace |
47 | 47 |
48 namespace content { | 48 namespace content { |
49 | 49 |
50 P2PSocketHostUdp::PendingPacket::PendingPacket( | 50 P2PSocketHostUdp::PendingPacket::PendingPacket( |
51 const net::IPEndPoint& to, | 51 const net::IPEndPoint& to, |
52 const std::vector<char>& content, | 52 const std::vector<char>& content, |
53 net::DiffServCodePoint dscp_, | 53 const talk_base::PacketOptions& options, |
54 uint64 id) | 54 uint64 id) |
55 : to(to), | 55 : to(to), |
56 data(new net::IOBuffer(content.size())), | 56 data(new net::IOBuffer(content.size())), |
57 size(content.size()), | 57 size(content.size()), |
58 dscp(dscp_), | 58 packet_options(options), |
59 id(id) { | 59 id(id) { |
60 memcpy(data->data(), &content[0], size); | 60 memcpy(data->data(), &content[0], size); |
61 } | 61 } |
62 | 62 |
63 P2PSocketHostUdp::PendingPacket::~PendingPacket() { | 63 P2PSocketHostUdp::PendingPacket::~PendingPacket() { |
64 } | 64 } |
65 | 65 |
66 P2PSocketHostUdp::P2PSocketHostUdp(IPC::Sender* message_sender, | 66 P2PSocketHostUdp::P2PSocketHostUdp(IPC::Sender* message_sender, |
67 int id, | 67 int id, |
68 P2PMessageThrottler* throttler) | 68 P2PMessageThrottler* throttler) |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 message_sender_->Send(new P2PMsg_OnDataReceived( | 172 message_sender_->Send(new P2PMsg_OnDataReceived( |
173 id_, recv_address_, data, base::TimeTicks::Now())); | 173 id_, recv_address_, data, base::TimeTicks::Now())); |
174 } else if (result < 0 && !IsTransientError(result)) { | 174 } else if (result < 0 && !IsTransientError(result)) { |
175 LOG(ERROR) << "Error when reading from UDP socket: " << result; | 175 LOG(ERROR) << "Error when reading from UDP socket: " << result; |
176 OnError(); | 176 OnError(); |
177 } | 177 } |
178 } | 178 } |
179 | 179 |
180 void P2PSocketHostUdp::Send(const net::IPEndPoint& to, | 180 void P2PSocketHostUdp::Send(const net::IPEndPoint& to, |
181 const std::vector<char>& data, | 181 const std::vector<char>& data, |
182 net::DiffServCodePoint dscp, | 182 const talk_base::PacketOptions& options, |
183 uint64 packet_id) { | 183 uint64 packet_id) { |
184 if (!socket_) { | 184 if (!socket_) { |
185 // The Send message may be sent after the an OnError message was | 185 // The Send message may be sent after the an OnError message was |
186 // sent by hasn't been processed the renderer. | 186 // sent by hasn't been processed the renderer. |
187 return; | 187 return; |
188 } | 188 } |
189 | 189 |
190 if (!ContainsKey(connected_peers_, to)) { | 190 if (!ContainsKey(connected_peers_, to)) { |
191 P2PSocketHost::StunMessageType type = P2PSocketHost::StunMessageType(); | 191 P2PSocketHost::StunMessageType type = P2PSocketHost::StunMessageType(); |
192 bool stun = GetStunPacketType(&*data.begin(), data.size(), &type); | 192 bool stun = GetStunPacketType(&*data.begin(), data.size(), &type); |
193 if (!stun || type == STUN_DATA_INDICATION) { | 193 if (!stun || type == STUN_DATA_INDICATION) { |
194 LOG(ERROR) << "Page tried to send a data packet to " << to.ToString() | 194 LOG(ERROR) << "Page tried to send a data packet to " << to.ToString() |
195 << " before STUN binding is finished."; | 195 << " before STUN binding is finished."; |
196 OnError(); | 196 OnError(); |
197 return; | 197 return; |
198 } | 198 } |
199 | 199 |
200 if (throttler_->DropNextPacket(data.size())) { | 200 if (throttler_->DropNextPacket(data.size())) { |
201 VLOG(0) << "STUN message is dropped due to high volume."; | 201 VLOG(0) << "STUN message is dropped due to high volume."; |
202 // Do not reset socket. | 202 // Do not reset socket. |
203 return; | 203 return; |
204 } | 204 } |
205 } | 205 } |
206 | 206 |
207 if (send_pending_) { | 207 if (send_pending_) { |
208 send_queue_.push_back(PendingPacket(to, data, dscp, packet_id)); | 208 send_queue_.push_back(PendingPacket(to, data, options, packet_id)); |
209 } else { | 209 } else { |
210 PendingPacket packet(to, data, dscp, packet_id); | 210 // TODO(mallinath: Remove unnecessary memcpy in this case. |
| 211 PendingPacket packet(to, data, options, packet_id); |
211 DoSend(packet); | 212 DoSend(packet); |
212 } | 213 } |
213 } | 214 } |
214 | 215 |
215 void P2PSocketHostUdp::DoSend(const PendingPacket& packet) { | 216 void P2PSocketHostUdp::DoSend(const PendingPacket& packet) { |
216 TRACE_EVENT_ASYNC_STEP_INTO1("p2p", "Send", packet.id, "UdpAsyncSendTo", | 217 TRACE_EVENT_ASYNC_STEP_INTO1("p2p", "Send", packet.id, "UdpAsyncSendTo", |
217 "size", packet.size); | 218 "size", packet.size); |
218 // Don't try to set DSCP in following conditions, | 219 // Don't try to set DSCP in following conditions, |
219 // 1. If the outgoing packet is set to DSCP_NO_CHANGE | 220 // 1. If the outgoing packet is set to DSCP_NO_CHANGE |
220 // 2. If no change in DSCP value from last packet | 221 // 2. If no change in DSCP value from last packet |
221 // 3. If there is any error in setting DSCP on socket. | 222 // 3. If there is any error in setting DSCP on socket. |
222 if (packet.dscp != net::DSCP_NO_CHANGE && | 223 net::DiffServCodePoint dscp = |
223 last_dscp_ != packet.dscp && last_dscp_ != net::DSCP_NO_CHANGE) { | 224 static_cast<net::DiffServCodePoint>(packet.packet_options.dscp); |
224 int result = socket_->SetDiffServCodePoint(packet.dscp); | 225 if (dscp != net::DSCP_NO_CHANGE && last_dscp_ != dscp && |
| 226 last_dscp_ != net::DSCP_NO_CHANGE) { |
| 227 int result = socket_->SetDiffServCodePoint(dscp); |
225 if (result == net::OK) { | 228 if (result == net::OK) { |
226 last_dscp_ = packet.dscp; | 229 last_dscp_ = dscp; |
227 } else if (!IsTransientError(result) && last_dscp_ != net::DSCP_CS0) { | 230 } else if (!IsTransientError(result) && last_dscp_ != net::DSCP_CS0) { |
228 // We receieved a non-transient error, and it seems we have | 231 // We receieved a non-transient error, and it seems we have |
229 // not changed the DSCP in the past, disable DSCP as it unlikely | 232 // not changed the DSCP in the past, disable DSCP as it unlikely |
230 // to work in the future. | 233 // to work in the future. |
231 last_dscp_ = net::DSCP_NO_CHANGE; | 234 last_dscp_ = net::DSCP_NO_CHANGE; |
232 } | 235 } |
233 } | 236 } |
234 int result = socket_->SendTo( | 237 int result = socket_->SendTo( |
235 packet.data.get(), | 238 packet.data.get(), |
236 packet.size, | 239 packet.size, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 case P2P_SOCKET_OPT_DSCP: | 305 case P2P_SOCKET_OPT_DSCP: |
303 return (net::OK == socket_->SetDiffServCodePoint( | 306 return (net::OK == socket_->SetDiffServCodePoint( |
304 static_cast<net::DiffServCodePoint>(value))) ? true : false; | 307 static_cast<net::DiffServCodePoint>(value))) ? true : false; |
305 default: | 308 default: |
306 NOTREACHED(); | 309 NOTREACHED(); |
307 return false; | 310 return false; |
308 } | 311 } |
309 } | 312 } |
310 | 313 |
311 } // namespace content | 314 } // namespace content |
OLD | NEW |