OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "mojo/services/network/udp_socket_impl.h" | 5 #include "mojo/services/network/udp_socket_impl.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <limits> | 10 #include <limits> |
(...skipping 16 matching lines...) Expand all Loading... |
27 const size_t kMaxWriteSize = 128 * 1024; | 27 const size_t kMaxWriteSize = 128 * 1024; |
28 const size_t kMaxPendingSendRequestsUpperbound = 128; | 28 const size_t kMaxPendingSendRequestsUpperbound = 128; |
29 const size_t kDefaultMaxPendingSendRequests = 32; | 29 const size_t kDefaultMaxPendingSendRequests = 32; |
30 | 30 |
31 } // namespace | 31 } // namespace |
32 | 32 |
33 UDPSocketImpl::PendingSendRequest::PendingSendRequest() {} | 33 UDPSocketImpl::PendingSendRequest::PendingSendRequest() {} |
34 | 34 |
35 UDPSocketImpl::PendingSendRequest::~PendingSendRequest() {} | 35 UDPSocketImpl::PendingSendRequest::~PendingSendRequest() {} |
36 | 36 |
37 UDPSocketImpl::UDPSocketImpl() | 37 UDPSocketImpl::UDPSocketImpl(InterfaceRequest<UDPSocket> request) |
38 : socket_(net::DatagramSocket::DEFAULT_BIND, net::RandIntCallback(), | 38 : binding_(this, request.Pass()), |
39 nullptr, net::NetLog::Source()), | 39 socket_(net::DatagramSocket::DEFAULT_BIND, |
| 40 net::RandIntCallback(), |
| 41 nullptr, |
| 42 net::NetLog::Source()), |
40 state_(NOT_BOUND_OR_CONNECTED), | 43 state_(NOT_BOUND_OR_CONNECTED), |
41 allow_address_reuse_(false), | 44 allow_address_reuse_(false), |
42 remaining_recv_slots_(0), | 45 remaining_recv_slots_(0), |
43 max_pending_send_requests_(kDefaultMaxPendingSendRequests) { | 46 max_pending_send_requests_(kDefaultMaxPendingSendRequests) { |
44 } | 47 } |
45 | 48 |
46 UDPSocketImpl::~UDPSocketImpl() { | 49 UDPSocketImpl::~UDPSocketImpl() { |
47 STLDeleteElements(&pending_send_requests_); | 50 STLDeleteElements(&pending_send_requests_); |
48 } | 51 } |
49 | 52 |
50 void UDPSocketImpl::AllowAddressReuse( | 53 void UDPSocketImpl::AllowAddressReuse( |
51 const Callback<void(NetworkErrorPtr)>& callback) { | 54 const Callback<void(NetworkErrorPtr)>& callback) { |
52 if (IsBoundOrConnected()) { | 55 if (IsBoundOrConnected()) { |
53 callback.Run(MakeNetworkError(net::ERR_FAILED)); | 56 callback.Run(MakeNetworkError(net::ERR_FAILED)); |
54 return; | 57 return; |
55 } | 58 } |
56 | 59 |
57 allow_address_reuse_ = true; | 60 allow_address_reuse_ = true; |
58 callback.Run(MakeNetworkError(net::OK)); | 61 callback.Run(MakeNetworkError(net::OK)); |
59 } | 62 } |
60 | 63 |
61 void UDPSocketImpl::Bind( | 64 void UDPSocketImpl::Bind( |
62 NetAddressPtr addr, | 65 NetAddressPtr addr, |
63 const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback) { | 66 const Callback<void(NetworkErrorPtr, |
| 67 NetAddressPtr, |
| 68 InterfaceRequest<UDPSocketReceiver>)>& callback) { |
64 int net_result = net::OK; | 69 int net_result = net::OK; |
65 bool opened = false; | 70 bool opened = false; |
66 | 71 |
67 do { | 72 do { |
68 if (IsBoundOrConnected()) { | 73 if (IsBoundOrConnected()) { |
69 net_result = net::ERR_FAILED; | 74 net_result = net::ERR_FAILED; |
70 break; | 75 break; |
71 } | 76 } |
72 | 77 |
73 net::IPEndPoint ip_end_point = addr.To<net::IPEndPoint>(); | 78 net::IPEndPoint ip_end_point = addr.To<net::IPEndPoint>(); |
(...skipping 17 matching lines...) Expand all Loading... |
91 if (net_result != net::OK) | 96 if (net_result != net::OK) |
92 break; | 97 break; |
93 | 98 |
94 net::IPEndPoint bound_ip_end_point; | 99 net::IPEndPoint bound_ip_end_point; |
95 net_result = socket_.GetLocalAddress(&bound_ip_end_point); | 100 net_result = socket_.GetLocalAddress(&bound_ip_end_point); |
96 if (net_result != net::OK) | 101 if (net_result != net::OK) |
97 break; | 102 break; |
98 | 103 |
99 state_ = BOUND; | 104 state_ = BOUND; |
100 callback.Run(MakeNetworkError(net_result), | 105 callback.Run(MakeNetworkError(net_result), |
101 NetAddress::From(bound_ip_end_point)); | 106 NetAddress::From(bound_ip_end_point), GetProxy(&receiver_)); |
102 | 107 |
103 if (remaining_recv_slots_ > 0) { | 108 if (remaining_recv_slots_ > 0) { |
104 DCHECK(!recvfrom_buffer_.get()); | 109 DCHECK(!recvfrom_buffer_.get()); |
105 DoRecvFrom(); | 110 DoRecvFrom(); |
106 } | 111 } |
107 return; | 112 return; |
108 } while (false); | 113 } while (false); |
109 | 114 |
110 DCHECK(net_result != net::OK); | 115 DCHECK(net_result != net::OK); |
111 if (opened) | 116 if (opened) |
112 socket_.Close(); | 117 socket_.Close(); |
113 callback.Run(MakeNetworkError(net_result), nullptr); | 118 callback.Run(MakeNetworkError(net_result), nullptr, nullptr); |
114 } | 119 } |
115 | 120 |
116 void UDPSocketImpl::Connect( | 121 void UDPSocketImpl::Connect( |
117 NetAddressPtr remote_addr, | 122 NetAddressPtr remote_addr, |
118 const Callback<void(NetworkErrorPtr, NetAddressPtr)>& callback) { | 123 const Callback<void(NetworkErrorPtr, |
| 124 NetAddressPtr, |
| 125 InterfaceRequest<UDPSocketReceiver>)>& callback) { |
119 int net_result = net::OK; | 126 int net_result = net::OK; |
120 bool opened = false; | 127 bool opened = false; |
121 | 128 |
122 do { | 129 do { |
123 if (IsBoundOrConnected()) { | 130 if (IsBoundOrConnected()) { |
124 net_result = net::ERR_FAILED; | 131 net_result = net::ERR_FAILED; |
125 break; | 132 break; |
126 } | 133 } |
127 | 134 |
128 net::IPEndPoint ip_end_point = remote_addr.To<net::IPEndPoint>(); | 135 net::IPEndPoint ip_end_point = remote_addr.To<net::IPEndPoint>(); |
(...skipping 11 matching lines...) Expand all Loading... |
140 if (net_result != net::OK) | 147 if (net_result != net::OK) |
141 break; | 148 break; |
142 | 149 |
143 net::IPEndPoint local_ip_end_point; | 150 net::IPEndPoint local_ip_end_point; |
144 net_result = socket_.GetLocalAddress(&local_ip_end_point); | 151 net_result = socket_.GetLocalAddress(&local_ip_end_point); |
145 if (net_result != net::OK) | 152 if (net_result != net::OK) |
146 break; | 153 break; |
147 | 154 |
148 state_ = CONNECTED; | 155 state_ = CONNECTED; |
149 callback.Run(MakeNetworkError(net_result), | 156 callback.Run(MakeNetworkError(net_result), |
150 NetAddress::From(local_ip_end_point)); | 157 NetAddress::From(local_ip_end_point), GetProxy(&receiver_)); |
151 | 158 |
152 if (remaining_recv_slots_ > 0) { | 159 if (remaining_recv_slots_ > 0) { |
153 DCHECK(!recvfrom_buffer_.get()); | 160 DCHECK(!recvfrom_buffer_.get()); |
154 DoRecvFrom(); | 161 DoRecvFrom(); |
155 } | 162 } |
156 return; | 163 return; |
157 } while (false); | 164 } while (false); |
158 | 165 |
159 DCHECK(net_result != net::OK); | 166 DCHECK(net_result != net::OK); |
160 if (opened) | 167 if (opened) |
161 socket_.Close(); | 168 socket_.Close(); |
162 callback.Run(MakeNetworkError(net_result), nullptr); | 169 callback.Run(MakeNetworkError(net_result), nullptr, nullptr); |
163 } | 170 } |
164 | 171 |
165 void UDPSocketImpl::SetSendBufferSize( | 172 void UDPSocketImpl::SetSendBufferSize( |
166 uint32_t size, | 173 uint32_t size, |
167 const Callback<void(NetworkErrorPtr)>& callback) { | 174 const Callback<void(NetworkErrorPtr)>& callback) { |
168 if (!IsBoundOrConnected()) { | 175 if (!IsBoundOrConnected()) { |
169 callback.Run(MakeNetworkError(net::ERR_FAILED)); | 176 callback.Run(MakeNetworkError(net::ERR_FAILED)); |
170 return; | 177 return; |
171 } | 178 } |
172 | 179 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 pending_send_requests_.resize(max_pending_send_requests_); | 216 pending_send_requests_.resize(max_pending_send_requests_); |
210 for (auto& discarded_request : discarded_requests) { | 217 for (auto& discarded_request : discarded_requests) { |
211 discarded_request->callback.Run( | 218 discarded_request->callback.Run( |
212 MakeNetworkError(net::ERR_INSUFFICIENT_RESOURCES)); | 219 MakeNetworkError(net::ERR_INSUFFICIENT_RESOURCES)); |
213 delete discarded_request; | 220 delete discarded_request; |
214 } | 221 } |
215 } | 222 } |
216 } | 223 } |
217 | 224 |
218 void UDPSocketImpl::ReceiveMore(uint32_t datagram_number) { | 225 void UDPSocketImpl::ReceiveMore(uint32_t datagram_number) { |
| 226 if (!receiver_) |
| 227 return; |
219 if (datagram_number == 0) | 228 if (datagram_number == 0) |
220 return; | 229 return; |
221 if (std::numeric_limits<size_t>::max() - remaining_recv_slots_ < | 230 if (std::numeric_limits<size_t>::max() - remaining_recv_slots_ < |
222 datagram_number) { | 231 datagram_number) { |
223 return; | 232 return; |
224 } | 233 } |
225 | 234 |
226 remaining_recv_slots_ += datagram_number; | 235 remaining_recv_slots_ += datagram_number; |
227 | 236 |
228 if (IsBoundOrConnected() && !recvfrom_buffer_.get()) { | 237 if (IsBoundOrConnected() && !recvfrom_buffer_.get()) { |
(...skipping 28 matching lines...) Expand all Loading... |
257 return; | 266 return; |
258 } | 267 } |
259 | 268 |
260 DCHECK_EQ(0u, pending_send_requests_.size()); | 269 DCHECK_EQ(0u, pending_send_requests_.size()); |
261 | 270 |
262 DoSendTo(dest_addr.Pass(), data.Pass(), callback); | 271 DoSendTo(dest_addr.Pass(), data.Pass(), callback); |
263 } | 272 } |
264 | 273 |
265 void UDPSocketImpl::DoRecvFrom() { | 274 void UDPSocketImpl::DoRecvFrom() { |
266 DCHECK(IsBoundOrConnected()); | 275 DCHECK(IsBoundOrConnected()); |
| 276 DCHECK(receiver_); |
267 DCHECK(!recvfrom_buffer_.get()); | 277 DCHECK(!recvfrom_buffer_.get()); |
268 DCHECK_GT(remaining_recv_slots_, 0u); | 278 DCHECK_GT(remaining_recv_slots_, 0u); |
269 | 279 |
270 recvfrom_buffer_ = new net::IOBuffer(kMaxReadSize); | 280 recvfrom_buffer_ = new net::IOBuffer(kMaxReadSize); |
271 | 281 |
272 // It is safe to use base::Unretained(this) because |socket_| is owned by this | 282 // It is safe to use base::Unretained(this) because |socket_| is owned by this |
273 // object. If this object gets destroyed (and so does |socket_|), the callback | 283 // object. If this object gets destroyed (and so does |socket_|), the callback |
274 // won't be called. | 284 // won't be called. |
275 int net_result = socket_.RecvFrom( | 285 int net_result = socket_.RecvFrom( |
276 recvfrom_buffer_.get(), | 286 recvfrom_buffer_.get(), |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 net_address = NetAddress::From(recvfrom_address_); | 340 net_address = NetAddress::From(recvfrom_address_); |
331 | 341 |
332 std::vector<uint8_t> data(net_result); | 342 std::vector<uint8_t> data(net_result); |
333 if (net_result > 0) | 343 if (net_result > 0) |
334 memcpy(&data[0], recvfrom_buffer_->data(), net_result); | 344 memcpy(&data[0], recvfrom_buffer_->data(), net_result); |
335 | 345 |
336 array.Swap(&data); | 346 array.Swap(&data); |
337 } | 347 } |
338 recvfrom_buffer_ = nullptr; | 348 recvfrom_buffer_ = nullptr; |
339 | 349 |
340 client()->OnReceived(MakeNetworkError(net_result), net_address.Pass(), | 350 receiver_->OnReceived(MakeNetworkError(net_result), net_address.Pass(), |
341 array.Pass()); | 351 array.Pass()); |
342 | |
343 DCHECK_GT(remaining_recv_slots_, 0u); | 352 DCHECK_GT(remaining_recv_slots_, 0u); |
344 remaining_recv_slots_--; | 353 remaining_recv_slots_--; |
345 if (remaining_recv_slots_ > 0) | 354 if (remaining_recv_slots_ > 0) |
346 DoRecvFrom(); | 355 DoRecvFrom(); |
347 } | 356 } |
348 | 357 |
349 void UDPSocketImpl::OnSendToCompleted( | 358 void UDPSocketImpl::OnSendToCompleted( |
350 const Callback<void(NetworkErrorPtr)>& callback, | 359 const Callback<void(NetworkErrorPtr)>& callback, |
351 int net_result) { | 360 int net_result) { |
352 DCHECK(sendto_buffer_.get()); | 361 DCHECK(sendto_buffer_.get()); |
353 | 362 |
354 sendto_buffer_ = nullptr; | 363 sendto_buffer_ = nullptr; |
355 | 364 |
356 callback.Run(MakeNetworkError(net_result)); | 365 callback.Run(MakeNetworkError(net_result)); |
357 | 366 |
358 if (pending_send_requests_.empty()) | 367 if (pending_send_requests_.empty()) |
359 return; | 368 return; |
360 | 369 |
361 scoped_ptr<PendingSendRequest> request(pending_send_requests_.front()); | 370 scoped_ptr<PendingSendRequest> request(pending_send_requests_.front()); |
362 pending_send_requests_.pop_front(); | 371 pending_send_requests_.pop_front(); |
363 | 372 |
364 DoSendTo(request->addr.Pass(), request->data.Pass(), request->callback); | 373 DoSendTo(request->addr.Pass(), request->data.Pass(), request->callback); |
365 } | 374 } |
366 | 375 |
367 } // namespace mojo | 376 } // namespace mojo |
OLD | NEW |