Chromium Code Reviews| 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 "net/udp/udp_socket_win.h" | 5 #include "net/udp/udp_socket_win.h" |
| 6 | 6 |
| 7 #include <mstcpip.h> | 7 #include <mstcpip.h> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/eintr_wrapper.h" | 10 #include "base/eintr_wrapper.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 static const int kBindRetries = 10; | 26 static const int kBindRetries = 10; |
| 27 static const int kPortStart = 1024; | 27 static const int kPortStart = 1024; |
| 28 static const int kPortEnd = 65535; | 28 static const int kPortEnd = 65535; |
| 29 | 29 |
| 30 } // namespace net | 30 } // namespace net |
| 31 | 31 |
| 32 namespace net { | 32 namespace net { |
| 33 | 33 |
| 34 void UDPSocketWin::ReadDelegate::OnObjectSignaled(HANDLE object) { | 34 // This class encapsulates all the state that has to be preserved as long as |
| 35 DCHECK_EQ(object, socket_->read_overlapped_.hEvent); | 35 // there is a network IO operation in progress. If the owner UDPSocketWin |
| 36 socket_->DidCompleteRead(); | 36 // is destroyed while an operation is in progress, the Core is detached and it |
| 37 // lives until the operation completes and the OS doesn't reference any resource | |
| 38 // declared on this class anymore. | |
| 39 class UDPSocketWin::Core : public base::RefCounted<Core> { | |
| 40 public: | |
| 41 explicit Core(UDPSocketWin* socket); | |
| 42 | |
| 43 // Start watching for the end of a read or write operation. | |
| 44 void WatchForRead(); | |
| 45 void WatchForWrite(); | |
| 46 | |
| 47 // The UDPSocketWin is going away. | |
| 48 void Detach() { socket_ = NULL; } | |
| 49 | |
| 50 // The separate OVERLAPPED variables for asynchronous operation. | |
| 51 OVERLAPPED read_overlapped_; | |
| 52 OVERLAPPED write_overlapped_; | |
| 53 | |
| 54 // The buffers used in Read() and Write(). | |
| 55 scoped_refptr<IOBuffer> read_iobuffer_; | |
| 56 scoped_refptr<IOBuffer> write_iobuffer_; | |
| 57 | |
| 58 // The address storage passed to WSARecvFrom(). | |
| 59 SockaddrStorage recv_addr_storage_; | |
| 60 | |
| 61 private: | |
| 62 friend class base::RefCounted<Core>; | |
| 63 | |
| 64 class ReadDelegate : public base::win::ObjectWatcher::Delegate { | |
| 65 public: | |
| 66 explicit ReadDelegate(Core* core) : core_(core) {} | |
| 67 virtual ~ReadDelegate() {} | |
| 68 | |
| 69 // base::ObjectWatcher::Delegate methods: | |
| 70 virtual void OnObjectSignaled(HANDLE object); | |
| 71 | |
| 72 private: | |
| 73 Core* const core_; | |
| 74 }; | |
| 75 | |
| 76 class WriteDelegate : public base::win::ObjectWatcher::Delegate { | |
| 77 public: | |
| 78 explicit WriteDelegate(Core* core) : core_(core) {} | |
| 79 virtual ~WriteDelegate() {} | |
| 80 | |
| 81 // base::ObjectWatcher::Delegate methods: | |
| 82 virtual void OnObjectSignaled(HANDLE object); | |
| 83 | |
| 84 private: | |
| 85 Core* const core_; | |
| 86 }; | |
| 87 | |
| 88 ~Core(); | |
| 89 | |
| 90 // The socket that created this object. | |
| 91 UDPSocketWin* socket_; | |
| 92 | |
| 93 // |reader_| handles the signals from |read_watcher_|. | |
| 94 ReadDelegate reader_; | |
| 95 // |writer_| handles the signals from |write_watcher_|. | |
| 96 WriteDelegate writer_; | |
| 97 | |
| 98 // |read_watcher_| watches for events from Read(). | |
| 99 base::win::ObjectWatcher read_watcher_; | |
| 100 // |write_watcher_| watches for events from Write(); | |
| 101 base::win::ObjectWatcher write_watcher_; | |
| 102 | |
| 103 DISALLOW_COPY_AND_ASSIGN(Core); | |
| 104 }; | |
| 105 | |
| 106 UDPSocketWin::Core::Core(UDPSocketWin* socket) | |
| 107 : socket_(socket), | |
| 108 ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)), | |
| 109 ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)) { | |
| 110 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | |
| 111 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | |
| 112 | |
| 113 read_overlapped_.hEvent = WSACreateEvent(); | |
| 114 write_overlapped_.hEvent = WSACreateEvent(); | |
| 37 } | 115 } |
| 38 | 116 |
| 39 void UDPSocketWin::WriteDelegate::OnObjectSignaled(HANDLE object) { | 117 UDPSocketWin::Core::~Core() { |
| 40 DCHECK_EQ(object, socket_->write_overlapped_.hEvent); | 118 // Make sure the message loop is not watching this object anymore. |
| 41 socket_->DidCompleteWrite(); | 119 read_watcher_.StopWatching(); |
| 120 write_watcher_.StopWatching(); | |
| 121 | |
| 122 WSACloseEvent(read_overlapped_.hEvent); | |
| 123 memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_)); | |
| 124 WSACloseEvent(write_overlapped_.hEvent); | |
| 125 memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_)); | |
| 42 } | 126 } |
| 43 | 127 |
| 128 void UDPSocketWin::Core::WatchForRead() { | |
| 129 // We grab an extra reference because there is an IO operation in progress. | |
| 130 // Balanced in ReadDelegate::OnObjectSignaled(). | |
| 131 AddRef(); | |
| 132 read_watcher_.StartWatching(read_overlapped_.hEvent, &reader_); | |
| 133 } | |
| 134 | |
| 135 void UDPSocketWin::Core::WatchForWrite() { | |
| 136 // We grab an extra reference because there is an IO operation in progress. | |
| 137 // Balanced in WriteDelegate::OnObjectSignaled(). | |
| 138 AddRef(); | |
| 139 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_); | |
| 140 } | |
| 141 | |
| 142 void UDPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) { | |
| 143 DCHECK_EQ(object, core_->read_overlapped_.hEvent); | |
| 144 if (core_->socket_) | |
| 145 core_->socket_->DidCompleteRead(); | |
| 146 | |
| 147 core_->Release(); | |
| 148 } | |
| 149 | |
| 150 void UDPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) { | |
| 151 DCHECK_EQ(object, core_->write_overlapped_.hEvent); | |
| 152 if (core_->socket_) | |
| 153 core_->socket_->DidCompleteWrite(); | |
| 154 | |
| 155 core_->Release(); | |
| 156 } | |
| 157 | |
| 158 //----------------------------------------------------------------------------- | |
| 159 | |
| 44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, | 160 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, |
| 45 const RandIntCallback& rand_int_cb, | 161 const RandIntCallback& rand_int_cb, |
| 46 net::NetLog* net_log, | 162 net::NetLog* net_log, |
| 47 const net::NetLog::Source& source) | 163 const net::NetLog::Source& source) |
| 48 : socket_(INVALID_SOCKET), | 164 : socket_(INVALID_SOCKET), |
| 49 socket_options_(0), | 165 socket_options_(0), |
| 50 bind_type_(bind_type), | 166 bind_type_(bind_type), |
| 51 rand_int_cb_(rand_int_cb), | 167 rand_int_cb_(rand_int_cb), |
| 52 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), | |
| 53 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), | |
| 54 recv_from_address_(NULL), | 168 recv_from_address_(NULL), |
| 55 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { | 169 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
| 56 EnsureWinsockInit(); | 170 EnsureWinsockInit(); |
| 57 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 171 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
| 58 source.ToEventParametersCallback()); | 172 source.ToEventParametersCallback()); |
| 59 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | |
| 60 read_overlapped_.hEvent = WSACreateEvent(); | |
| 61 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | |
| 62 write_overlapped_.hEvent = WSACreateEvent(); | |
| 63 if (bind_type == DatagramSocket::RANDOM_BIND) | 173 if (bind_type == DatagramSocket::RANDOM_BIND) |
| 64 DCHECK(!rand_int_cb.is_null()); | 174 DCHECK(!rand_int_cb.is_null()); |
| 65 } | 175 } |
| 66 | 176 |
| 67 UDPSocketWin::~UDPSocketWin() { | 177 UDPSocketWin::~UDPSocketWin() { |
| 68 Close(); | 178 Close(); |
| 69 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); | 179 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); |
| 70 } | 180 } |
| 71 | 181 |
| 72 void UDPSocketWin::Close() { | 182 void UDPSocketWin::Close() { |
| 73 DCHECK(CalledOnValidThread()); | 183 DCHECK(CalledOnValidThread()); |
| 74 | 184 |
| 75 if (!is_connected()) | 185 if (!is_connected()) |
| 76 return; | 186 return; |
| 77 | 187 |
| 78 // Zero out any pending read/write callback state. | 188 // Zero out any pending read/write callback state. |
| 79 read_callback_.Reset(); | 189 read_callback_.Reset(); |
| 80 recv_from_address_ = NULL; | 190 recv_from_address_ = NULL; |
| 81 write_callback_.Reset(); | 191 write_callback_.Reset(); |
| 82 | 192 |
| 83 read_watcher_.StopWatching(); | |
| 84 write_watcher_.StopWatching(); | |
| 85 | |
| 86 WSACloseEvent(read_overlapped_.hEvent); | |
| 87 memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_)); | |
| 88 WSACloseEvent(write_overlapped_.hEvent); | |
| 89 memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_)); | |
| 90 | |
| 91 closesocket(socket_); | 193 closesocket(socket_); |
| 92 socket_ = INVALID_SOCKET; | 194 socket_ = INVALID_SOCKET; |
| 195 | |
| 196 core_->Detach(); | |
| 197 core_ = NULL; | |
| 93 } | 198 } |
| 94 | 199 |
| 95 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { | 200 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { |
| 96 DCHECK(CalledOnValidThread()); | 201 DCHECK(CalledOnValidThread()); |
| 97 DCHECK(address); | 202 DCHECK(address); |
| 98 if (!is_connected()) | 203 if (!is_connected()) |
| 99 return ERR_SOCKET_NOT_CONNECTED; | 204 return ERR_SOCKET_NOT_CONNECTED; |
| 100 | 205 |
| 101 // TODO(szym): Simplify. http://crbug.com/126152 | 206 // TODO(szym): Simplify. http://crbug.com/126152 |
| 102 if (!remote_address_.get()) { | 207 if (!remote_address_.get()) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 DCHECK_NE(INVALID_SOCKET, socket_); | 253 DCHECK_NE(INVALID_SOCKET, socket_); |
| 149 DCHECK(read_callback_.is_null()); | 254 DCHECK(read_callback_.is_null()); |
| 150 DCHECK(!recv_from_address_); | 255 DCHECK(!recv_from_address_); |
| 151 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 256 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
| 152 DCHECK_GT(buf_len, 0); | 257 DCHECK_GT(buf_len, 0); |
| 153 | 258 |
| 154 int nread = InternalRecvFrom(buf, buf_len, address); | 259 int nread = InternalRecvFrom(buf, buf_len, address); |
| 155 if (nread != ERR_IO_PENDING) | 260 if (nread != ERR_IO_PENDING) |
| 156 return nread; | 261 return nread; |
| 157 | 262 |
| 158 read_iobuffer_ = buf; | |
| 159 read_callback_ = callback; | 263 read_callback_ = callback; |
| 160 recv_from_address_ = address; | 264 recv_from_address_ = address; |
| 161 return ERR_IO_PENDING; | 265 return ERR_IO_PENDING; |
| 162 } | 266 } |
| 163 | 267 |
| 164 int UDPSocketWin::Write(IOBuffer* buf, | 268 int UDPSocketWin::Write(IOBuffer* buf, |
| 165 int buf_len, | 269 int buf_len, |
| 166 const CompletionCallback& callback) { | 270 const CompletionCallback& callback) { |
| 167 return SendToOrWrite(buf, buf_len, NULL, callback); | 271 return SendToOrWrite(buf, buf_len, NULL, callback); |
| 168 } | 272 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 184 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 288 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
| 185 DCHECK_GT(buf_len, 0); | 289 DCHECK_GT(buf_len, 0); |
| 186 DCHECK(!send_to_address_.get()); | 290 DCHECK(!send_to_address_.get()); |
| 187 | 291 |
| 188 int nwrite = InternalSendTo(buf, buf_len, address); | 292 int nwrite = InternalSendTo(buf, buf_len, address); |
| 189 if (nwrite != ERR_IO_PENDING) | 293 if (nwrite != ERR_IO_PENDING) |
| 190 return nwrite; | 294 return nwrite; |
| 191 | 295 |
| 192 if (address) | 296 if (address) |
| 193 send_to_address_.reset(new IPEndPoint(*address)); | 297 send_to_address_.reset(new IPEndPoint(*address)); |
| 194 write_iobuffer_ = buf; | |
| 195 write_callback_ = callback; | 298 write_callback_ = callback; |
| 196 return ERR_IO_PENDING; | 299 return ERR_IO_PENDING; |
| 197 } | 300 } |
| 198 | 301 |
| 199 int UDPSocketWin::Connect(const IPEndPoint& address) { | 302 int UDPSocketWin::Connect(const IPEndPoint& address) { |
| 200 net_log_.BeginEvent(NetLog::TYPE_UDP_CONNECT, | 303 net_log_.BeginEvent(NetLog::TYPE_UDP_CONNECT, |
| 201 CreateNetLogUDPConnectCallback(&address)); | 304 CreateNetLogUDPConnectCallback(&address)); |
| 202 int rv = InternalConnect(address); | 305 int rv = InternalConnect(address); |
| 203 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv); | 306 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv); |
| 204 return rv; | 307 return rv; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 return rv; | 346 return rv; |
| 244 local_address_.reset(); | 347 local_address_.reset(); |
| 245 return rv; | 348 return rv; |
| 246 } | 349 } |
| 247 | 350 |
| 248 int UDPSocketWin::CreateSocket(const IPEndPoint& address) { | 351 int UDPSocketWin::CreateSocket(const IPEndPoint& address) { |
| 249 socket_ = WSASocket(address.GetFamily(), SOCK_DGRAM, IPPROTO_UDP, NULL, 0, | 352 socket_ = WSASocket(address.GetFamily(), SOCK_DGRAM, IPPROTO_UDP, NULL, 0, |
| 250 WSA_FLAG_OVERLAPPED); | 353 WSA_FLAG_OVERLAPPED); |
| 251 if (socket_ == INVALID_SOCKET) | 354 if (socket_ == INVALID_SOCKET) |
| 252 return MapSystemError(WSAGetLastError()); | 355 return MapSystemError(WSAGetLastError()); |
| 356 core_ = new Core(this); | |
| 253 return OK; | 357 return OK; |
| 254 } | 358 } |
| 255 | 359 |
| 256 bool UDPSocketWin::SetReceiveBufferSize(int32 size) { | 360 bool UDPSocketWin::SetReceiveBufferSize(int32 size) { |
| 257 DCHECK(CalledOnValidThread()); | 361 DCHECK(CalledOnValidThread()); |
| 258 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, | 362 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, |
| 259 reinterpret_cast<const char*>(&size), sizeof(size)); | 363 reinterpret_cast<const char*>(&size), sizeof(size)); |
| 260 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno; | 364 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno; |
| 261 return rv == 0; | 365 return rv == 0; |
| 262 } | 366 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 DCHECK(!write_callback_.is_null()); | 402 DCHECK(!write_callback_.is_null()); |
| 299 | 403 |
| 300 // since Run may result in Write being called, clear write_callback_ up front. | 404 // since Run may result in Write being called, clear write_callback_ up front. |
| 301 CompletionCallback c = write_callback_; | 405 CompletionCallback c = write_callback_; |
| 302 write_callback_.Reset(); | 406 write_callback_.Reset(); |
| 303 c.Run(rv); | 407 c.Run(rv); |
| 304 } | 408 } |
| 305 | 409 |
| 306 void UDPSocketWin::DidCompleteRead() { | 410 void UDPSocketWin::DidCompleteRead() { |
| 307 DWORD num_bytes, flags; | 411 DWORD num_bytes, flags; |
| 308 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, | 412 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, |
| 309 &num_bytes, FALSE, &flags); | 413 &num_bytes, FALSE, &flags); |
| 310 WSAResetEvent(read_overlapped_.hEvent); | 414 WSAResetEvent(core_->read_overlapped_.hEvent); |
| 311 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 415 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
| 312 // Convert address. | 416 // Convert address. |
| 313 if (recv_from_address_ && result >= 0) { | 417 if (recv_from_address_ && result >= 0) { |
| 314 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) | 418 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) |
| 315 result = ERR_FAILED; | 419 result = ERR_FAILED; |
| 316 } | 420 } |
| 317 LogRead(result, read_iobuffer_->data()); | 421 LogRead(result, core_->read_iobuffer_->data()); |
| 318 read_iobuffer_ = NULL; | 422 core_->read_iobuffer_ = NULL; |
| 319 recv_from_address_ = NULL; | 423 recv_from_address_ = NULL; |
| 320 DoReadCallback(result); | 424 DoReadCallback(result); |
| 321 } | 425 } |
| 322 | 426 |
| 323 void UDPSocketWin::LogRead(int result, const char* bytes) const { | 427 void UDPSocketWin::LogRead(int result, const char* bytes) const { |
| 324 if (result < 0) { | 428 if (result < 0) { |
| 325 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); | 429 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); |
| 326 return; | 430 return; |
| 327 } | 431 } |
| 328 | 432 |
| 329 if (net_log_.IsLoggingAllEvents()) { | 433 if (net_log_.IsLoggingAllEvents()) { |
| 330 // Get address for logging, if |address| is NULL. | 434 // Get address for logging, if |address| is NULL. |
| 331 IPEndPoint address; | 435 IPEndPoint address; |
| 332 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); | 436 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); |
| 333 net_log_.AddEvent( | 437 net_log_.AddEvent( |
| 334 NetLog::TYPE_UDP_BYTES_RECEIVED, | 438 NetLog::TYPE_UDP_BYTES_RECEIVED, |
| 335 CreateNetLogUDPDataTranferCallback( | 439 CreateNetLogUDPDataTranferCallback( |
| 336 result, bytes, | 440 result, bytes, |
| 337 is_address_valid ? &address : NULL)); | 441 is_address_valid ? &address : NULL)); |
| 338 } | 442 } |
| 339 | 443 |
| 340 base::StatsCounter read_bytes("udp.read_bytes"); | 444 base::StatsCounter read_bytes("udp.read_bytes"); |
| 341 read_bytes.Add(result); | 445 read_bytes.Add(result); |
| 342 } | 446 } |
| 343 | 447 |
| 344 void UDPSocketWin::DidCompleteWrite() { | 448 void UDPSocketWin::DidCompleteWrite() { |
| 345 DWORD num_bytes, flags; | 449 DWORD num_bytes, flags; |
| 346 BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_, | 450 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, |
| 347 &num_bytes, FALSE, &flags); | 451 &num_bytes, FALSE, &flags); |
| 348 WSAResetEvent(write_overlapped_.hEvent); | 452 WSAResetEvent(core_->write_overlapped_.hEvent); |
| 349 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 453 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
| 350 LogWrite(result, write_iobuffer_->data(), send_to_address_.get()); | 454 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); |
| 351 | 455 |
| 352 send_to_address_.reset(); | 456 send_to_address_.reset(); |
| 353 write_iobuffer_ = NULL; | 457 core_->write_iobuffer_ = NULL; |
| 354 DoWriteCallback(result); | 458 DoWriteCallback(result); |
| 355 } | 459 } |
| 356 | 460 |
| 357 void UDPSocketWin::LogWrite(int result, | 461 void UDPSocketWin::LogWrite(int result, |
| 358 const char* bytes, | 462 const char* bytes, |
| 359 const IPEndPoint* address) const { | 463 const IPEndPoint* address) const { |
| 360 if (result < 0) { | 464 if (result < 0) { |
| 361 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); | 465 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); |
| 362 return; | 466 return; |
| 363 } | 467 } |
| 364 | 468 |
| 365 if (net_log_.IsLoggingAllEvents()) { | 469 if (net_log_.IsLoggingAllEvents()) { |
| 366 net_log_.AddEvent( | 470 net_log_.AddEvent( |
| 367 NetLog::TYPE_UDP_BYTES_SENT, | 471 NetLog::TYPE_UDP_BYTES_SENT, |
| 368 CreateNetLogUDPDataTranferCallback(result, bytes, address)); | 472 CreateNetLogUDPDataTranferCallback(result, bytes, address)); |
| 369 } | 473 } |
| 370 | 474 |
| 371 base::StatsCounter write_bytes("udp.write_bytes"); | 475 base::StatsCounter write_bytes("udp.write_bytes"); |
| 372 write_bytes.Add(result); | 476 write_bytes.Add(result); |
| 373 } | 477 } |
| 374 | 478 |
| 375 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, | 479 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, |
| 376 IPEndPoint* address) { | 480 IPEndPoint* address) { |
| 377 recv_addr_len_ = sizeof(recv_addr_storage_); | 481 DCHECK(!core_->read_iobuffer_); |
| 378 struct sockaddr* addr = | 482 SockaddrStorage& storage = core_->recv_addr_storage_; |
|
wtc
2012/09/12 19:07:39
Nit: "recv_addr" is a better name than "storage" f
| |
| 379 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); | 483 storage.addr_len = sizeof(storage.addr_storage); |
| 380 | 484 |
| 381 WSABUF read_buffer; | 485 WSABUF read_buffer; |
| 382 read_buffer.buf = buf->data(); | 486 read_buffer.buf = buf->data(); |
| 383 read_buffer.len = buf_len; | 487 read_buffer.len = buf_len; |
| 384 | 488 |
| 385 DWORD flags = 0; | 489 DWORD flags = 0; |
| 386 DWORD num; | 490 DWORD num; |
| 387 CHECK_NE(INVALID_SOCKET, socket_); | 491 CHECK_NE(INVALID_SOCKET, socket_); |
| 388 AssertEventNotSignaled(read_overlapped_.hEvent); | 492 AssertEventNotSignaled(core_->read_overlapped_.hEvent); |
| 389 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr, | 493 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr, |
| 390 &recv_addr_len_, &read_overlapped_, NULL); | 494 &storage.addr_len, &core_->read_overlapped_, NULL); |
| 391 if (rv == 0) { | 495 if (rv == 0) { |
| 392 if (ResetEventIfSignaled(read_overlapped_.hEvent)) { | 496 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { |
| 393 int result = num; | 497 int result = num; |
| 394 // Convert address. | 498 // Convert address. |
| 395 if (address && result >= 0) { | 499 if (address && result >= 0) { |
| 396 if (!ReceiveAddressToIPEndpoint(address)) | 500 if (!ReceiveAddressToIPEndpoint(address)) |
| 397 result = ERR_FAILED; | 501 result = ERR_FAILED; |
| 398 } | 502 } |
| 399 LogRead(result, buf->data()); | 503 LogRead(result, buf->data()); |
| 400 return result; | 504 return result; |
| 401 } | 505 } |
| 402 } else { | 506 } else { |
| 403 int os_error = WSAGetLastError(); | 507 int os_error = WSAGetLastError(); |
| 404 if (os_error != WSA_IO_PENDING) { | 508 if (os_error != WSA_IO_PENDING) { |
| 405 int result = MapSystemError(os_error); | 509 int result = MapSystemError(os_error); |
| 406 LogRead(result, NULL); | 510 LogRead(result, NULL); |
| 407 return result; | 511 return result; |
| 408 } | 512 } |
| 409 } | 513 } |
| 410 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); | 514 core_->WatchForRead(); |
| 515 core_->read_iobuffer_ = buf; | |
| 411 return ERR_IO_PENDING; | 516 return ERR_IO_PENDING; |
| 412 } | 517 } |
| 413 | 518 |
| 414 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, | 519 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, |
| 415 const IPEndPoint* address) { | 520 const IPEndPoint* address) { |
| 521 DCHECK(!core_->write_iobuffer_); | |
| 416 SockaddrStorage storage; | 522 SockaddrStorage storage; |
| 417 struct sockaddr* addr = storage.addr; | 523 struct sockaddr* addr = storage.addr; |
| 418 // Convert address. | 524 // Convert address. |
| 419 if (!address) { | 525 if (!address) { |
| 420 addr = NULL; | 526 addr = NULL; |
| 421 storage.addr_len = 0; | 527 storage.addr_len = 0; |
| 422 } else { | 528 } else { |
| 423 if (!address->ToSockAddr(addr, &storage.addr_len)) { | 529 if (!address->ToSockAddr(addr, &storage.addr_len)) { |
| 424 int result = ERR_FAILED; | 530 int result = ERR_FAILED; |
| 425 LogWrite(result, NULL, NULL); | 531 LogWrite(result, NULL, NULL); |
| 426 return result; | 532 return result; |
| 427 } | 533 } |
| 428 } | 534 } |
| 429 | 535 |
| 430 WSABUF write_buffer; | 536 WSABUF write_buffer; |
| 431 write_buffer.buf = buf->data(); | 537 write_buffer.buf = buf->data(); |
| 432 write_buffer.len = buf_len; | 538 write_buffer.len = buf_len; |
| 433 | 539 |
| 434 DWORD flags = 0; | 540 DWORD flags = 0; |
| 435 DWORD num; | 541 DWORD num; |
| 436 AssertEventNotSignaled(write_overlapped_.hEvent); | 542 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
| 437 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, | 543 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, |
| 438 addr, storage.addr_len, &write_overlapped_, NULL); | 544 addr, storage.addr_len, &core_->write_overlapped_, NULL); |
| 439 if (rv == 0) { | 545 if (rv == 0) { |
| 440 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { | 546 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
| 441 int result = num; | 547 int result = num; |
| 442 LogWrite(result, buf->data(), address); | 548 LogWrite(result, buf->data(), address); |
| 443 return result; | 549 return result; |
| 444 } | 550 } |
| 445 } else { | 551 } else { |
| 446 int os_error = WSAGetLastError(); | 552 int os_error = WSAGetLastError(); |
| 447 if (os_error != WSA_IO_PENDING) { | 553 if (os_error != WSA_IO_PENDING) { |
| 448 int result = MapSystemError(os_error); | 554 int result = MapSystemError(os_error); |
| 449 LogWrite(result, NULL, NULL); | 555 LogWrite(result, NULL, NULL); |
| 450 return result; | 556 return result; |
| 451 } | 557 } |
| 452 } | 558 } |
| 453 | 559 |
| 454 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); | 560 core_->WatchForWrite(); |
| 561 core_->write_iobuffer_ = buf; | |
| 455 return ERR_IO_PENDING; | 562 return ERR_IO_PENDING; |
| 456 } | 563 } |
| 457 | 564 |
| 458 int UDPSocketWin::SetSocketOptions() { | 565 int UDPSocketWin::SetSocketOptions() { |
| 459 BOOL true_value = 1; | 566 BOOL true_value = 1; |
| 460 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { | 567 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { |
| 461 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, | 568 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, |
| 462 reinterpret_cast<const char*>(&true_value), | 569 reinterpret_cast<const char*>(&true_value), |
| 463 sizeof(true_value)); | 570 sizeof(true_value)); |
| 464 if (rv < 0) | 571 if (rv < 0) |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 490 | 597 |
| 491 for (int i = 0; i < kBindRetries; ++i) { | 598 for (int i = 0; i < kBindRetries; ++i) { |
| 492 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 599 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
| 493 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 600 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
| 494 return rv; | 601 return rv; |
| 495 } | 602 } |
| 496 return DoBind(IPEndPoint(ip, 0)); | 603 return DoBind(IPEndPoint(ip, 0)); |
| 497 } | 604 } |
| 498 | 605 |
| 499 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | 606 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
| 500 const struct sockaddr* addr = | 607 SockaddrStorage& storage = core_->recv_addr_storage_; |
| 501 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); | 608 return address->FromSockAddr(storage.addr, storage.addr_len); |
| 502 return address->FromSockAddr(addr, recv_addr_len_); | |
| 503 } | 609 } |
| 504 | 610 |
| 505 } // namespace net | 611 } // namespace net |
| OLD | NEW |