| 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 |