| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/eintr_wrapper.h" | 9 #include "base/eintr_wrapper.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, | 44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, |
| 45 const RandIntCallback& rand_int_cb, | 45 const RandIntCallback& rand_int_cb, |
| 46 net::NetLog* net_log, | 46 net::NetLog* net_log, |
| 47 const net::NetLog::Source& source) | 47 const net::NetLog::Source& source) |
| 48 : socket_(INVALID_SOCKET), | 48 : socket_(INVALID_SOCKET), |
| 49 bind_type_(bind_type), | 49 bind_type_(bind_type), |
| 50 rand_int_cb_(rand_int_cb), | 50 rand_int_cb_(rand_int_cb), |
| 51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), | 51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), |
| 52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), | 52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), |
| 53 recv_from_address_(NULL), | 53 recv_from_address_(NULL), |
| 54 old_read_callback_(NULL), | |
| 55 write_callback_(NULL), | |
| 56 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { | 54 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
| 57 EnsureWinsockInit(); | 55 EnsureWinsockInit(); |
| 58 scoped_refptr<NetLog::EventParameters> params; | 56 scoped_refptr<NetLog::EventParameters> params; |
| 59 if (source.is_valid()) | 57 if (source.is_valid()) |
| 60 params = new NetLogSourceParameter("source_dependency", source); | 58 params = new NetLogSourceParameter("source_dependency", source); |
| 61 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 59 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
| 62 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 60 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
| 63 read_overlapped_.hEvent = WSACreateEvent(); | 61 read_overlapped_.hEvent = WSACreateEvent(); |
| 64 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 62 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
| 65 write_overlapped_.hEvent = WSACreateEvent(); | 63 write_overlapped_.hEvent = WSACreateEvent(); |
| 66 if (bind_type == DatagramSocket::RANDOM_BIND) | 64 if (bind_type == DatagramSocket::RANDOM_BIND) |
| 67 DCHECK(!rand_int_cb.is_null()); | 65 DCHECK(!rand_int_cb.is_null()); |
| 68 } | 66 } |
| 69 | 67 |
| 70 UDPSocketWin::~UDPSocketWin() { | 68 UDPSocketWin::~UDPSocketWin() { |
| 71 Close(); | 69 Close(); |
| 72 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 70 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); |
| 73 } | 71 } |
| 74 | 72 |
| 75 void UDPSocketWin::Close() { | 73 void UDPSocketWin::Close() { |
| 76 DCHECK(CalledOnValidThread()); | 74 DCHECK(CalledOnValidThread()); |
| 77 | 75 |
| 78 if (!is_connected()) | 76 if (!is_connected()) |
| 79 return; | 77 return; |
| 80 | 78 |
| 81 // Zero out any pending read/write callback state. | 79 // Zero out any pending read/write callback state. |
| 82 old_read_callback_ = NULL; | |
| 83 read_callback_.Reset(); | 80 read_callback_.Reset(); |
| 84 recv_from_address_ = NULL; | 81 recv_from_address_ = NULL; |
| 85 write_callback_ = NULL; | 82 write_callback_.Reset(); |
| 86 | 83 |
| 87 read_watcher_.StopWatching(); | 84 read_watcher_.StopWatching(); |
| 88 write_watcher_.StopWatching(); | 85 write_watcher_.StopWatching(); |
| 89 | 86 |
| 90 closesocket(socket_); | 87 closesocket(socket_); |
| 91 socket_ = INVALID_SOCKET; | 88 socket_ = INVALID_SOCKET; |
| 92 } | 89 } |
| 93 | 90 |
| 94 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { | 91 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { |
| 95 DCHECK(CalledOnValidThread()); | 92 DCHECK(CalledOnValidThread()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 return ERR_FAILED; | 127 return ERR_FAILED; |
| 131 local_address_.reset(address.release()); | 128 local_address_.reset(address.release()); |
| 132 } | 129 } |
| 133 | 130 |
| 134 *address = *local_address_; | 131 *address = *local_address_; |
| 135 return OK; | 132 return OK; |
| 136 } | 133 } |
| 137 | 134 |
| 138 int UDPSocketWin::Read(IOBuffer* buf, | 135 int UDPSocketWin::Read(IOBuffer* buf, |
| 139 int buf_len, | 136 int buf_len, |
| 140 OldCompletionCallback* callback) { | |
| 141 return RecvFrom(buf, buf_len, NULL, callback); | |
| 142 } | |
| 143 int UDPSocketWin::Read(IOBuffer* buf, | |
| 144 int buf_len, | |
| 145 const CompletionCallback& callback) { | 137 const CompletionCallback& callback) { |
| 146 return RecvFrom(buf, buf_len, NULL, callback); | 138 return RecvFrom(buf, buf_len, NULL, callback); |
| 147 } | 139 } |
| 148 | 140 |
| 149 int UDPSocketWin::RecvFrom(IOBuffer* buf, | 141 int UDPSocketWin::RecvFrom(IOBuffer* buf, |
| 150 int buf_len, | 142 int buf_len, |
| 151 IPEndPoint* address, | 143 IPEndPoint* address, |
| 152 OldCompletionCallback* callback) { | |
| 153 DCHECK(CalledOnValidThread()); | |
| 154 DCHECK_NE(INVALID_SOCKET, socket_); | |
| 155 DCHECK(!old_read_callback_ && read_callback_.is_null()); | |
| 156 DCHECK(!recv_from_address_); | |
| 157 DCHECK(callback); // Synchronous operation not supported. | |
| 158 DCHECK_GT(buf_len, 0); | |
| 159 | |
| 160 int nread = InternalRecvFrom(buf, buf_len, address); | |
| 161 if (nread != ERR_IO_PENDING) | |
| 162 return nread; | |
| 163 | |
| 164 read_iobuffer_ = buf; | |
| 165 old_read_callback_ = callback; | |
| 166 recv_from_address_ = address; | |
| 167 return ERR_IO_PENDING; | |
| 168 } | |
| 169 int UDPSocketWin::RecvFrom(IOBuffer* buf, | |
| 170 int buf_len, | |
| 171 IPEndPoint* address, | |
| 172 const CompletionCallback& callback) { | 144 const CompletionCallback& callback) { |
| 173 DCHECK(CalledOnValidThread()); | 145 DCHECK(CalledOnValidThread()); |
| 174 DCHECK_NE(INVALID_SOCKET, socket_); | 146 DCHECK_NE(INVALID_SOCKET, socket_); |
| 175 DCHECK(!old_read_callback_ && read_callback_.is_null()); | 147 DCHECK(read_callback_.is_null()); |
| 176 DCHECK(!recv_from_address_); | 148 DCHECK(!recv_from_address_); |
| 177 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 149 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
| 178 DCHECK_GT(buf_len, 0); | 150 DCHECK_GT(buf_len, 0); |
| 179 | 151 |
| 180 int nread = InternalRecvFrom(buf, buf_len, address); | 152 int nread = InternalRecvFrom(buf, buf_len, address); |
| 181 if (nread != ERR_IO_PENDING) | 153 if (nread != ERR_IO_PENDING) |
| 182 return nread; | 154 return nread; |
| 183 | 155 |
| 184 read_iobuffer_ = buf; | 156 read_iobuffer_ = buf; |
| 185 read_callback_ = callback; | 157 read_callback_ = callback; |
| 186 recv_from_address_ = address; | 158 recv_from_address_ = address; |
| 187 return ERR_IO_PENDING; | 159 return ERR_IO_PENDING; |
| 188 } | 160 } |
| 189 | 161 |
| 190 int UDPSocketWin::Write(IOBuffer* buf, | 162 int UDPSocketWin::Write(IOBuffer* buf, |
| 191 int buf_len, | 163 int buf_len, |
| 192 OldCompletionCallback* callback) { | 164 const CompletionCallback& callback) { |
| 193 return SendToOrWrite(buf, buf_len, NULL, callback); | 165 return SendToOrWrite(buf, buf_len, NULL, callback); |
| 194 } | 166 } |
| 195 | 167 |
| 196 int UDPSocketWin::SendTo(IOBuffer* buf, | 168 int UDPSocketWin::SendTo(IOBuffer* buf, |
| 197 int buf_len, | 169 int buf_len, |
| 198 const IPEndPoint& address, | 170 const IPEndPoint& address, |
| 199 OldCompletionCallback* callback) { | 171 const CompletionCallback& callback) { |
| 200 return SendToOrWrite(buf, buf_len, &address, callback); | 172 return SendToOrWrite(buf, buf_len, &address, callback); |
| 201 } | 173 } |
| 202 | 174 |
| 203 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, | 175 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, |
| 204 int buf_len, | 176 int buf_len, |
| 205 const IPEndPoint* address, | 177 const IPEndPoint* address, |
| 206 OldCompletionCallback* callback) { | 178 const CompletionCallback& callback) { |
| 207 DCHECK(CalledOnValidThread()); | 179 DCHECK(CalledOnValidThread()); |
| 208 DCHECK_NE(INVALID_SOCKET, socket_); | 180 DCHECK_NE(INVALID_SOCKET, socket_); |
| 209 DCHECK(!write_callback_); | 181 DCHECK(write_callback_.is_null()); |
| 210 DCHECK(callback); // Synchronous operation not supported. | 182 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
| 211 DCHECK_GT(buf_len, 0); | 183 DCHECK_GT(buf_len, 0); |
| 212 DCHECK(!send_to_address_.get()); | 184 DCHECK(!send_to_address_.get()); |
| 213 | 185 |
| 214 int nwrite = InternalSendTo(buf, buf_len, address); | 186 int nwrite = InternalSendTo(buf, buf_len, address); |
| 215 if (nwrite != ERR_IO_PENDING) | 187 if (nwrite != ERR_IO_PENDING) |
| 216 return nwrite; | 188 return nwrite; |
| 217 | 189 |
| 218 if (address) | 190 if (address) |
| 219 send_to_address_.reset(new IPEndPoint(*address)); | 191 send_to_address_.reset(new IPEndPoint(*address)); |
| 220 write_iobuffer_ = buf; | 192 write_iobuffer_ = buf; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 bool UDPSocketWin::SetSendBufferSize(int32 size) { | 263 bool UDPSocketWin::SetSendBufferSize(int32 size) { |
| 292 DCHECK(CalledOnValidThread()); | 264 DCHECK(CalledOnValidThread()); |
| 293 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 265 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
| 294 reinterpret_cast<const char*>(&size), sizeof(size)); | 266 reinterpret_cast<const char*>(&size), sizeof(size)); |
| 295 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; | 267 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; |
| 296 return rv == 0; | 268 return rv == 0; |
| 297 } | 269 } |
| 298 | 270 |
| 299 void UDPSocketWin::DoReadCallback(int rv) { | 271 void UDPSocketWin::DoReadCallback(int rv) { |
| 300 DCHECK_NE(rv, ERR_IO_PENDING); | 272 DCHECK_NE(rv, ERR_IO_PENDING); |
| 301 DCHECK(old_read_callback_ || !read_callback_.is_null()); | 273 DCHECK(!read_callback_.is_null()); |
| 302 | 274 |
| 303 // since Run may result in Read being called, clear read_callback_ up front. | 275 // since Run may result in Read being called, clear read_callback_ up front. |
| 304 if (old_read_callback_) { | 276 CompletionCallback c = read_callback_; |
| 305 OldCompletionCallback* c = old_read_callback_; | 277 read_callback_.Reset(); |
| 306 old_read_callback_ = NULL; | 278 c.Run(rv); |
| 307 c->Run(rv); | |
| 308 } else { | |
| 309 CompletionCallback c = read_callback_; | |
| 310 read_callback_.Reset(); | |
| 311 c.Run(rv); | |
| 312 } | |
| 313 } | 279 } |
| 314 | 280 |
| 315 void UDPSocketWin::DoWriteCallback(int rv) { | 281 void UDPSocketWin::DoWriteCallback(int rv) { |
| 316 DCHECK_NE(rv, ERR_IO_PENDING); | 282 DCHECK_NE(rv, ERR_IO_PENDING); |
| 317 DCHECK(write_callback_); | 283 DCHECK(!write_callback_.is_null()); |
| 318 | 284 |
| 319 // since Run may result in Write being called, clear write_callback_ up front. | 285 // since Run may result in Write being called, clear write_callback_ up front. |
| 320 OldCompletionCallback* c = write_callback_; | 286 CompletionCallback c = write_callback_; |
| 321 write_callback_ = NULL; | 287 write_callback_.Reset(); |
| 322 c->Run(rv); | 288 c.Run(rv); |
| 323 } | 289 } |
| 324 | 290 |
| 325 void UDPSocketWin::DidCompleteRead() { | 291 void UDPSocketWin::DidCompleteRead() { |
| 326 DWORD num_bytes, flags; | 292 DWORD num_bytes, flags; |
| 327 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, | 293 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, |
| 328 &num_bytes, FALSE, &flags); | 294 &num_bytes, FALSE, &flags); |
| 329 WSAResetEvent(read_overlapped_.hEvent); | 295 WSAResetEvent(read_overlapped_.hEvent); |
| 330 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 296 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
| 331 // Convert address. | 297 // Convert address. |
| 332 if (recv_from_address_ && result >= 0) { | 298 if (recv_from_address_ && result >= 0) { |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 return DoBind(IPEndPoint(ip, 0)); | 469 return DoBind(IPEndPoint(ip, 0)); |
| 504 } | 470 } |
| 505 | 471 |
| 506 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | 472 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
| 507 const struct sockaddr* addr = | 473 const struct sockaddr* addr = |
| 508 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); | 474 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); |
| 509 return address->FromSockAddr(addr, recv_addr_len_); | 475 return address->FromSockAddr(addr, recv_addr_len_); |
| 510 } | 476 } |
| 511 | 477 |
| 512 } // namespace net | 478 } // namespace net |
| OLD | NEW |