Chromium Code Reviews| 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" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/metrics/stats_counters.h" | 12 #include "base/metrics/stats_counters.h" |
| 13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 14 #include "net/base/address_list_net_log_param.h" | |
| 14 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
| 15 #include "net/base/ip_endpoint.h" | 16 #include "net/base/ip_endpoint.h" |
| 16 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
| 17 #include "net/base/net_log.h" | 18 #include "net/base/net_log.h" |
| 18 #include "net/base/net_util.h" | 19 #include "net/base/net_util.h" |
| 19 #include "net/base/winsock_init.h" | 20 #include "net/base/winsock_init.h" |
| 20 #include "net/base/winsock_util.h" | 21 #include "net/base/winsock_util.h" |
| 22 #include "net/udp/udp_data_transfer_param.h" | |
| 21 | 23 |
| 22 namespace { | 24 namespace { |
| 23 | 25 |
| 24 static const int kBindRetries = 10; | 26 static const int kBindRetries = 10; |
| 25 static const int kPortStart = 1024; | 27 static const int kPortStart = 1024; |
| 26 static const int kPortEnd = 65535; | 28 static const int kPortEnd = 65535; |
| 27 | 29 |
| 28 } // namespace net | 30 } // namespace net |
| 29 | 31 |
| 30 namespace net { | 32 namespace net { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 44 net::NetLog* net_log, | 46 net::NetLog* net_log, |
| 45 const net::NetLog::Source& source) | 47 const net::NetLog::Source& source) |
| 46 : socket_(INVALID_SOCKET), | 48 : socket_(INVALID_SOCKET), |
| 47 bind_type_(bind_type), | 49 bind_type_(bind_type), |
| 48 rand_int_cb_(rand_int_cb), | 50 rand_int_cb_(rand_int_cb), |
| 49 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), | 51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), |
| 50 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), | 52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), |
| 51 recv_from_address_(NULL), | 53 recv_from_address_(NULL), |
| 52 read_callback_(NULL), | 54 read_callback_(NULL), |
| 53 write_callback_(NULL), | 55 write_callback_(NULL), |
| 54 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 56 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
| 55 EnsureWinsockInit(); | 57 EnsureWinsockInit(); |
| 56 scoped_refptr<NetLog::EventParameters> params; | 58 scoped_refptr<NetLog::EventParameters> params; |
| 57 if (source.is_valid()) | 59 if (source.is_valid()) |
| 58 params = new NetLogSourceParameter("source_dependency", source); | 60 params = new NetLogSourceParameter("source_dependency", source); |
| 59 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 61 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
| 60 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 62 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
| 61 read_overlapped_.hEvent = WSACreateEvent(); | 63 read_overlapped_.hEvent = WSACreateEvent(); |
| 62 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 64 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
| 63 write_overlapped_.hEvent = WSACreateEvent(); | 65 write_overlapped_.hEvent = WSACreateEvent(); |
| 64 if (bind_type == DatagramSocket::RANDOM_BIND) | 66 if (bind_type == DatagramSocket::RANDOM_BIND) |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 | 176 |
| 175 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, | 177 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, |
| 176 int buf_len, | 178 int buf_len, |
| 177 const IPEndPoint* address, | 179 const IPEndPoint* address, |
| 178 OldCompletionCallback* callback) { | 180 OldCompletionCallback* callback) { |
| 179 DCHECK(CalledOnValidThread()); | 181 DCHECK(CalledOnValidThread()); |
| 180 DCHECK_NE(INVALID_SOCKET, socket_); | 182 DCHECK_NE(INVALID_SOCKET, socket_); |
| 181 DCHECK(!write_callback_); | 183 DCHECK(!write_callback_); |
| 182 DCHECK(callback); // Synchronous operation not supported. | 184 DCHECK(callback); // Synchronous operation not supported. |
| 183 DCHECK_GT(buf_len, 0); | 185 DCHECK_GT(buf_len, 0); |
| 186 DCHECK(!send_to_address_.get()); | |
| 184 | 187 |
| 185 int nwrite = InternalSendTo(buf, buf_len, address); | 188 int nwrite = InternalSendTo(buf, buf_len, address); |
| 186 if (nwrite != ERR_IO_PENDING) | 189 if (nwrite != ERR_IO_PENDING) |
| 187 return nwrite; | 190 return nwrite; |
| 188 | 191 |
| 192 if (address) | |
| 193 send_to_address_.reset(new IPEndPoint(*address)); | |
| 189 write_iobuffer_ = buf; | 194 write_iobuffer_ = buf; |
| 190 write_callback_ = callback; | 195 write_callback_ = callback; |
| 191 return ERR_IO_PENDING; | 196 return ERR_IO_PENDING; |
| 192 } | 197 } |
| 193 | 198 |
| 194 int UDPSocketWin::Connect(const IPEndPoint& address) { | 199 int UDPSocketWin::Connect(const IPEndPoint& address) { |
| 200 net_log_.BeginEvent( | |
| 201 NetLog::TYPE_UDP_CONNECT, | |
| 202 make_scoped_refptr(new NetLogStringParameter("address", | |
| 203 address.ToString()))); | |
| 204 int rv = InternalConnect(address); | |
| 205 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv); | |
| 206 return rv; | |
| 207 } | |
| 208 | |
| 209 int UDPSocketWin::InternalConnect(const IPEndPoint& address) { | |
| 195 DCHECK(!is_connected()); | 210 DCHECK(!is_connected()); |
| 196 DCHECK(!remote_address_.get()); | 211 DCHECK(!remote_address_.get()); |
| 197 int rv = CreateSocket(address); | 212 int rv = CreateSocket(address); |
| 198 if (rv < 0) | 213 if (rv < 0) |
| 199 return rv; | 214 return rv; |
| 200 | 215 |
| 201 if (bind_type_ == DatagramSocket::RANDOM_BIND) | 216 if (bind_type_ == DatagramSocket::RANDOM_BIND) |
| 202 rv = RandomBind(address); | 217 rv = RandomBind(address); |
| 203 // else connect() does the DatagramSocket::DEFAULT_BIND | 218 // else connect() does the DatagramSocket::DEFAULT_BIND |
| 204 | 219 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 write_callback_ = NULL; | 273 write_callback_ = NULL; |
| 259 c->Run(rv); | 274 c->Run(rv); |
| 260 } | 275 } |
| 261 | 276 |
| 262 void UDPSocketWin::DidCompleteRead() { | 277 void UDPSocketWin::DidCompleteRead() { |
| 263 DWORD num_bytes, flags; | 278 DWORD num_bytes, flags; |
| 264 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, | 279 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, |
| 265 &num_bytes, FALSE, &flags); | 280 &num_bytes, FALSE, &flags); |
| 266 WSAResetEvent(read_overlapped_.hEvent); | 281 WSAResetEvent(read_overlapped_.hEvent); |
| 267 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 282 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
| 268 if (ok) { | 283 result = LogRead(result, read_iobuffer_->data(), recv_from_address_); |
| 269 if (!ProcessSuccessfulRead(num_bytes, recv_from_address_)) | |
| 270 result = ERR_FAILED; | |
| 271 } | |
| 272 read_iobuffer_ = NULL; | 284 read_iobuffer_ = NULL; |
| 273 recv_from_address_ = NULL; | 285 recv_from_address_ = NULL; |
| 274 DoReadCallback(result); | 286 DoReadCallback(result); |
| 275 } | 287 } |
| 276 | 288 |
| 277 bool UDPSocketWin::ProcessSuccessfulRead(int num_bytes, IPEndPoint* address) { | 289 int UDPSocketWin::LogRead(int result, |
| 278 base::StatsCounter read_bytes("udp.read_bytes"); | 290 const char* bytes, |
| 279 read_bytes.Add(num_bytes); | 291 IPEndPoint* address) const { |
| 292 const struct sockaddr* addr = | |
| 293 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); | |
| 280 | 294 |
| 281 // Convert address. | 295 // Convert address. |
| 282 if (address) { | 296 if (address && result >= 0) { |
| 283 struct sockaddr* addr = | |
| 284 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); | |
| 285 if (!address->FromSockAddr(addr, recv_addr_len_)) | 297 if (!address->FromSockAddr(addr, recv_addr_len_)) |
|
Sergey Ulanov
2011/10/17 17:48:13
This should be moved to DidCompleteRead()
mmenke
2011/10/17 19:41:38
Done. Also had to add it to InternalRecvFrom, as i
| |
| 286 return false; | 298 result = ERR_FAILED; |
| 287 } | 299 } |
| 288 | 300 |
| 289 return true; | 301 if (result < 0) { |
| 302 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); | |
| 303 return result; | |
| 304 } | |
| 305 | |
| 306 if (net_log_.IsLoggingAllEvents()) { | |
| 307 // Get address for logging, if |address| is NULL. | |
| 308 IPEndPoint address_on_stack; | |
| 309 if (!address) { | |
| 310 if (address_on_stack.FromSockAddr(addr, recv_addr_len_)) | |
| 311 address = &address_on_stack; | |
| 312 } | |
| 313 net_log_.AddEvent( | |
| 314 NetLog::TYPE_UDP_BYTES_RECEIVED, | |
| 315 make_scoped_refptr( | |
| 316 new UDPDataTransferNetLogParam(result, bytes, | |
| 317 net_log_.IsLoggingBytes(), | |
| 318 address))); | |
| 319 } | |
| 320 | |
| 321 base::StatsCounter read_bytes("udp.read_bytes"); | |
| 322 read_bytes.Add(result); | |
| 323 return result; | |
| 290 } | 324 } |
| 291 | 325 |
| 292 void UDPSocketWin::DidCompleteWrite() { | 326 void UDPSocketWin::DidCompleteWrite() { |
| 293 DWORD num_bytes, flags; | 327 DWORD num_bytes, flags; |
| 294 BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_, | 328 BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_, |
| 295 &num_bytes, FALSE, &flags); | 329 &num_bytes, FALSE, &flags); |
| 296 WSAResetEvent(write_overlapped_.hEvent); | 330 WSAResetEvent(write_overlapped_.hEvent); |
| 297 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 331 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
| 298 if (ok) | 332 result = LogWrite(result, write_iobuffer_->data(), send_to_address_.get()); |
| 299 ProcessSuccessfulWrite(num_bytes); | 333 |
| 334 send_to_address_.reset(); | |
| 300 write_iobuffer_ = NULL; | 335 write_iobuffer_ = NULL; |
| 301 DoWriteCallback(result); | 336 DoWriteCallback(result); |
| 302 } | 337 } |
| 303 | 338 |
| 304 void UDPSocketWin::ProcessSuccessfulWrite(int num_bytes) { | 339 int UDPSocketWin::LogWrite(int result, |
| 340 const char* bytes, | |
| 341 const IPEndPoint* address) const { | |
| 342 if (result < 0) { | |
| 343 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); | |
| 344 return result; | |
| 345 } | |
| 346 | |
| 347 if (net_log_.IsLoggingAllEvents()) { | |
| 348 net_log_.AddEvent( | |
| 349 NetLog::TYPE_UDP_BYTES_SENT, | |
| 350 make_scoped_refptr( | |
| 351 new UDPDataTransferNetLogParam(result, bytes, | |
| 352 net_log_.IsLoggingBytes(), | |
| 353 address))); | |
| 354 } | |
| 355 | |
| 305 base::StatsCounter write_bytes("udp.write_bytes"); | 356 base::StatsCounter write_bytes("udp.write_bytes"); |
| 306 write_bytes.Add(num_bytes); | 357 write_bytes.Add(result); |
| 358 return result; | |
| 307 } | 359 } |
| 308 | 360 |
| 309 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, | 361 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, |
| 310 IPEndPoint* address) { | 362 IPEndPoint* address) { |
| 311 recv_addr_len_ = sizeof(recv_addr_storage_); | 363 recv_addr_len_ = sizeof(recv_addr_storage_); |
| 312 struct sockaddr* addr = | 364 struct sockaddr* addr = |
| 313 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); | 365 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); |
| 314 | 366 |
| 315 WSABUF read_buffer; | 367 WSABUF read_buffer; |
| 316 read_buffer.buf = buf->data(); | 368 read_buffer.buf = buf->data(); |
| 317 read_buffer.len = buf_len; | 369 read_buffer.len = buf_len; |
| 318 | 370 |
| 319 DWORD flags = 0; | 371 DWORD flags = 0; |
| 320 DWORD num; | 372 DWORD num; |
| 321 AssertEventNotSignaled(read_overlapped_.hEvent); | 373 AssertEventNotSignaled(read_overlapped_.hEvent); |
| 322 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr, | 374 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr, |
| 323 &recv_addr_len_, &read_overlapped_, NULL); | 375 &recv_addr_len_, &read_overlapped_, NULL); |
| 324 if (rv == 0) { | 376 if (rv == 0) { |
| 325 if (ResetEventIfSignaled(read_overlapped_.hEvent)) { | 377 if (ResetEventIfSignaled(read_overlapped_.hEvent)) |
| 326 if (!ProcessSuccessfulRead(num, address)) | 378 return LogRead(num, buf->data(), address); |
| 327 return ERR_FAILED; | |
| 328 return static_cast<int>(num); | |
| 329 } | |
| 330 } else { | 379 } else { |
| 331 int os_error = WSAGetLastError(); | 380 int os_error = WSAGetLastError(); |
| 332 if (os_error != WSA_IO_PENDING) | 381 if (os_error != WSA_IO_PENDING) |
| 333 return MapSystemError(os_error); | 382 return LogRead(MapSystemError(os_error), NULL, NULL); |
| 334 } | 383 } |
| 335 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); | 384 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); |
| 336 return ERR_IO_PENDING; | 385 return ERR_IO_PENDING; |
| 337 } | 386 } |
| 338 | 387 |
| 339 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, | 388 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, |
| 340 const IPEndPoint* address) { | 389 const IPEndPoint* address) { |
| 341 struct sockaddr_storage addr_storage; | 390 struct sockaddr_storage addr_storage; |
| 342 size_t addr_len = sizeof(addr_storage); | 391 size_t addr_len = sizeof(addr_storage); |
| 343 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | 392 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); |
| 344 | 393 |
| 345 // Convert address. | 394 // Convert address. |
| 346 if (!address) { | 395 if (!address) { |
| 347 addr = NULL; | 396 addr = NULL; |
| 348 addr_len = 0; | 397 addr_len = 0; |
| 349 } else { | 398 } else { |
| 350 if (!address->ToSockAddr(addr, &addr_len)) | 399 if (!address->ToSockAddr(addr, &addr_len)) |
| 351 return ERR_FAILED; | 400 return LogWrite(ERR_FAILED, NULL, NULL); |
| 352 } | 401 } |
| 353 | 402 |
| 354 WSABUF write_buffer; | 403 WSABUF write_buffer; |
| 355 write_buffer.buf = buf->data(); | 404 write_buffer.buf = buf->data(); |
| 356 write_buffer.len = buf_len; | 405 write_buffer.len = buf_len; |
| 357 | 406 |
| 358 DWORD flags = 0; | 407 DWORD flags = 0; |
| 359 DWORD num; | 408 DWORD num; |
| 360 AssertEventNotSignaled(write_overlapped_.hEvent); | 409 AssertEventNotSignaled(write_overlapped_.hEvent); |
| 361 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, | 410 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, |
| 362 addr, addr_len, &write_overlapped_, NULL); | 411 addr, addr_len, &write_overlapped_, NULL); |
| 363 if (rv == 0) { | 412 if (rv == 0) { |
| 364 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { | 413 if (ResetEventIfSignaled(write_overlapped_.hEvent)) |
| 365 ProcessSuccessfulWrite(num); | 414 return LogWrite(num, buf->data(), address); |
| 366 return static_cast<int>(num); | |
| 367 } | |
| 368 } else { | 415 } else { |
| 369 int os_error = WSAGetLastError(); | 416 int os_error = WSAGetLastError(); |
| 370 if (os_error != WSA_IO_PENDING) | 417 if (os_error != WSA_IO_PENDING) |
| 371 return MapSystemError(os_error); | 418 return LogWrite(MapSystemError(os_error), NULL, NULL); |
| 372 } | 419 } |
| 373 | 420 |
| 374 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); | 421 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); |
| 375 return ERR_IO_PENDING; | 422 return ERR_IO_PENDING; |
| 376 } | 423 } |
| 377 | 424 |
| 378 int UDPSocketWin::DoBind(const IPEndPoint& address) { | 425 int UDPSocketWin::DoBind(const IPEndPoint& address) { |
| 379 struct sockaddr_storage addr_storage; | 426 struct sockaddr_storage addr_storage; |
| 380 size_t addr_len = sizeof(addr_storage); | 427 size_t addr_len = sizeof(addr_storage); |
| 381 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | 428 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 393 | 440 |
| 394 for (int i = 0; i < kBindRetries; ++i) { | 441 for (int i = 0; i < kBindRetries; ++i) { |
| 395 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 442 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
| 396 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 443 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
| 397 return rv; | 444 return rv; |
| 398 } | 445 } |
| 399 return DoBind(IPEndPoint(ip, 0)); | 446 return DoBind(IPEndPoint(ip, 0)); |
| 400 } | 447 } |
| 401 | 448 |
| 402 } // namespace net | 449 } // namespace net |
| OLD | NEW |