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 3 // found in the LICENSE file. 4 5 #include "net/udp/udp_socket_win.h" 6 7 #include <mstcpip.h> 8 9 #include "base/callback.h" 10 #include "base/lazy_instance.h" 11 #include "base/logging.h" 12 #include "base/message_loop/message_loop.h" 13 #include "base/metrics/histogram.h" 14 #include "base/metrics/sparse_histogram.h" 15 #include "base/metrics/stats_counters.h" 16 #include "base/rand_util.h" 17 #include "net/base/io_buffer.h" 18 #include "net/base/ip_endpoint.h" 19 #include "net/base/net_errors.h" 20 #include "net/base/net_log.h" 21 #include "net/base/net_util.h" 22 #include "net/base/winsock_init.h" 23 #include "net/base/winsock_util.h" 24 #include "net/socket/socket_descriptor.h" 25 #include "net/udp/udp_net_log_parameters.h" 26 27 namespace { 28 29 const int kBindRetries = 10; 30 const int kPortStart = 1024; 31 const int kPortEnd = 65535; 32 33 } // namespace 34 35 namespace net { 36 37 // This class encapsulates all the state that has to be preserved as long as 38 // there is a network IO operation in progress. If the owner UDPSocketWin 39 // is destroyed while an operation is in progress, the Core is detached and it 40 // lives until the operation completes and the OS doesn't reference any resource 41 // declared on this class anymore. 42 class UDPSocketWin::Core : public base::RefCounted<Core> { 43 public: 44 explicit Core(UDPSocketWin* socket); 45 46 // Start watching for the end of a read or write operation. 47 void WatchForRead(); 48 void WatchForWrite(); 49 50 // The UDPSocketWin is going away. 51 void Detach() { socket_ = NULL; } 52 53 // The separate OVERLAPPED variables for asynchronous operation. 54 OVERLAPPED read_overlapped_; 55 OVERLAPPED write_overlapped_; 56 57 // The buffers used in Read() and Write(). 58 scoped_refptr<IOBuffer> read_iobuffer_; 59 scoped_refptr<IOBuffer> write_iobuffer_; 60 61 // The address storage passed to WSARecvFrom(). 62 SockaddrStorage recv_addr_storage_; 63 64 private: 65 friend class base::RefCounted<Core>; 66 67 class ReadDelegate : public base::win::ObjectWatcher::Delegate { 68 public: 69 explicit ReadDelegate(Core* core) : core_(core) {} 70 virtual ~ReadDelegate() {} 71 72 // base::ObjectWatcher::Delegate methods: 73 virtual void OnObjectSignaled(HANDLE object); 74 75 private: 76 Core* const core_; 77 }; 78 79 class WriteDelegate : public base::win::ObjectWatcher::Delegate { 80 public: 81 explicit WriteDelegate(Core* core) : core_(core) {} 82 virtual ~WriteDelegate() {} 83 84 // base::ObjectWatcher::Delegate methods: 85 virtual void OnObjectSignaled(HANDLE object); 86 87 private: 88 Core* const core_; 89 }; 90 91 ~Core(); 92 93 // The socket that created this object. 94 UDPSocketWin* socket_; 95 96 // |reader_| handles the signals from |read_watcher_|. 97 ReadDelegate reader_; 98 // |writer_| handles the signals from |write_watcher_|. 99 WriteDelegate writer_; 100 101 // |read_watcher_| watches for events from Read(). 102 base::win::ObjectWatcher read_watcher_; 103 // |write_watcher_| watches for events from Write(); 104 base::win::ObjectWatcher write_watcher_; 105 106 DISALLOW_COPY_AND_ASSIGN(Core); 107 }; 108 109 UDPSocketWin::Core::Core(UDPSocketWin* socket) 110 : socket_(socket), 111 reader_(this), 112 writer_(this) { 113 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); 114 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); 115 116 read_overlapped_.hEvent = WSACreateEvent(); 117 write_overlapped_.hEvent = WSACreateEvent(); 118 } 119 120 UDPSocketWin::Core::~Core() { 121 // Make sure the message loop is not watching this object anymore. 122 read_watcher_.StopWatching(); 123 write_watcher_.StopWatching(); 124 125 WSACloseEvent(read_overlapped_.hEvent); 126 memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_)); 127 WSACloseEvent(write_overlapped_.hEvent); 128 memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_)); 129 } 130 131 void UDPSocketWin::Core::WatchForRead() { 132 // We grab an extra reference because there is an IO operation in progress. 133 // Balanced in ReadDelegate::OnObjectSignaled(). 134 AddRef(); 135 read_watcher_.StartWatching(read_overlapped_.hEvent, &reader_); 136 } 137 138 void UDPSocketWin::Core::WatchForWrite() { 139 // We grab an extra reference because there is an IO operation in progress. 140 // Balanced in WriteDelegate::OnObjectSignaled(). 141 AddRef(); 142 write_watcher_.StartWatching(write_overlapped_.hEvent, &writer_); 143 } 144 145 void UDPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) { 146 DCHECK_EQ(object, core_->read_overlapped_.hEvent); 147 if (core_->socket_) 148 core_->socket_->DidCompleteRead(); 149 150 core_->Release(); 151 } 152 153 void UDPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) { 154 DCHECK_EQ(object, core_->write_overlapped_.hEvent); 155 if (core_->socket_) 156 core_->socket_->DidCompleteWrite(); 157 158 core_->Release(); 159 } 160 //----------------------------------------------------------------------------- 161 162 QwaveAPI::QwaveAPI() : qwave_supported_(false) { 163 HMODULE qwave = LoadLibrary(L"qwave.dll"); 164 if (!qwave) 165 return; 166 create_handle_func_ = 167 (CreateHandleFn)GetProcAddress(qwave, "QOSCreateHandle"); 168 close_handle_func_ = 169 (CloseHandleFn)GetProcAddress(qwave, "QOSCloseHandle"); 170 add_socket_to_flow_func_ = 171 (AddSocketToFlowFn)GetProcAddress(qwave, "QOSAddSocketToFlow"); 172 remove_socket_from_flow_func_ = 173 (RemoveSocketFromFlowFn)GetProcAddress(qwave, "QOSRemoveSocketFromFlow"); 174 set_flow_func_ = (SetFlowFn)GetProcAddress(qwave, "QOSSetFlow"); 175 176 if (create_handle_func_ && close_handle_func_ && 177 add_socket_to_flow_func_ && remove_socket_from_flow_func_ && 178 set_flow_func_) { 179 qwave_supported_ = true; 180 } 181 } 182 183 QwaveAPI& QwaveAPI::Get() { 184 static base::LazyInstance<QwaveAPI>::Leaky lazy_qwave = 185 LAZY_INSTANCE_INITIALIZER; 186 return lazy_qwave.Get(); 187 } 188 189 bool QwaveAPI::qwave_supported() const { 190 return qwave_supported_; 191 } 192 BOOL QwaveAPI::CreateHandle(PQOS_VERSION version, PHANDLE handle) { 193 return create_handle_func_(version, handle); 194 } 195 BOOL QwaveAPI::CloseHandle(HANDLE handle) { 196 return close_handle_func_(handle); 197 } 198 199 BOOL QwaveAPI::AddSocketToFlow(HANDLE handle, 200 SOCKET socket, 201 PSOCKADDR addr, 202 QOS_TRAFFIC_TYPE traffic_type, 203 DWORD flags, 204 PQOS_FLOWID flow_id) { 205 return add_socket_to_flow_func_(handle, 206 socket, 207 addr, 208 traffic_type, 209 flags, 210 flow_id); 211 } 212 213 BOOL QwaveAPI::RemoveSocketFromFlow(HANDLE handle, 214 SOCKET socket, 215 QOS_FLOWID flow_id, 216 DWORD reserved) { 217 return remove_socket_from_flow_func_(handle, socket, flow_id, reserved); 218 } 219 220 BOOL QwaveAPI::SetFlow(HANDLE handle, 221 QOS_FLOWID flow_id, 222 QOS_SET_FLOW op, 223 ULONG size, 224 PVOID data, 225 DWORD reserved, 226 LPOVERLAPPED overlapped) { 227 return set_flow_func_(handle, 228 flow_id, 229 op, 230 size, 231 data, 232 reserved, 233 overlapped); 234 } 235 236 237 //----------------------------------------------------------------------------- 238 239 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, 240 const RandIntCallback& rand_int_cb, 241 net::NetLog* net_log, 242 const net::NetLog::Source& source) 243 : socket_(INVALID_SOCKET), 244 addr_family_(0), 245 socket_options_(SOCKET_OPTION_MULTICAST_LOOP), 246 multicast_interface_(0), 247 multicast_time_to_live_(1), 248 bind_type_(bind_type), 249 rand_int_cb_(rand_int_cb), 250 recv_from_address_(NULL), 251 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)), 252 qos_handle_(NULL), 253 qos_flow_id_(0) { 254 EnsureWinsockInit(); 255 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 256 source.ToEventParametersCallback()); 257 if (bind_type == DatagramSocket::RANDOM_BIND) 258 DCHECK(!rand_int_cb.is_null()); 259 } 260 261 UDPSocketWin::~UDPSocketWin() { 262 Close(); 263 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); 264 } 265 266 void UDPSocketWin::Close() { 267 DCHECK(CalledOnValidThread()); 268 269 if (!is_connected()) 270 return; 271 272 if (qos_handle_) { 273 QwaveAPI::Get().CloseHandle(qos_handle_); 274 } 275 276 // Zero out any pending read/write callback state. 277 read_callback_.Reset(); 278 recv_from_address_ = NULL; 279 write_callback_.Reset(); 280 281 base::TimeTicks start_time = base::TimeTicks::Now(); 282 closesocket(socket_); 283 UMA_HISTOGRAM_TIMES("Net.UDPSocketWinClose", 284 base::TimeTicks::Now() - start_time); 285 socket_ = INVALID_SOCKET; 286 addr_family_ = 0; 287 288 core_->Detach(); 289 core_ = NULL; 290 } 291 292 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { 293 DCHECK(CalledOnValidThread()); 294 DCHECK(address); 295 if (!is_connected()) 296 return ERR_SOCKET_NOT_CONNECTED; 297 298 // TODO(szym): Simplify. http://crbug.com/126152 299 if (!remote_address_.get()) { 300 SockaddrStorage storage; 301 if (getpeername(socket_, storage.addr, &storage.addr_len)) 302 return MapSystemError(WSAGetLastError()); 303 scoped_ptr<IPEndPoint> address(new IPEndPoint()); 304 if (!address->FromSockAddr(storage.addr, storage.addr_len)) 305 return ERR_ADDRESS_INVALID; 306 remote_address_.reset(address.release()); 307 } 308 309 *address = *remote_address_; 310 return OK; 311 } 312 313 int UDPSocketWin::GetLocalAddress(IPEndPoint* address) const { 314 DCHECK(CalledOnValidThread()); 315 DCHECK(address); 316 if (!is_connected()) 317 return ERR_SOCKET_NOT_CONNECTED; 318 319 // TODO(szym): Simplify. http://crbug.com/126152 320 if (!local_address_.get()) { 321 SockaddrStorage storage; 322 if (getsockname(socket_, storage.addr, &storage.addr_len)) 323 return MapSystemError(WSAGetLastError()); 324 scoped_ptr<IPEndPoint> address(new IPEndPoint()); 325 if (!address->FromSockAddr(storage.addr, storage.addr_len)) 326 return ERR_ADDRESS_INVALID; 327 local_address_.reset(address.release()); 328 net_log_.AddEvent(NetLog::TYPE_UDP_LOCAL_ADDRESS, 329 CreateNetLogUDPConnectCallback(local_address_.get())); 330 } 331 332 *address = *local_address_; 333 return OK; 334 } 335 336 int UDPSocketWin::Read(IOBuffer* buf, 337 int buf_len, 338 const CompletionCallback& callback) { 339 return RecvFrom(buf, buf_len, NULL, callback); 340 } 341 342 int UDPSocketWin::RecvFrom(IOBuffer* buf, 343 int buf_len, 344 IPEndPoint* address, 345 const CompletionCallback& callback) { 346 DCHECK(CalledOnValidThread()); 347 DCHECK_NE(INVALID_SOCKET, socket_); 348 CHECK(read_callback_.is_null()); 349 DCHECK(!recv_from_address_); 350 DCHECK(!callback.is_null()); // Synchronous operation not supported. 351 DCHECK_GT(buf_len, 0); 352 353 int nread = InternalRecvFrom(buf, buf_len, address); 354 if (nread != ERR_IO_PENDING) 355 return nread; 356 357 read_callback_ = callback; 358 recv_from_address_ = address; 359 return ERR_IO_PENDING; 360 } 361 362 int UDPSocketWin::Write(IOBuffer* buf, 363 int buf_len, 364 const CompletionCallback& callback) { 365 return SendToOrWrite(buf, buf_len, NULL, callback); 366 } 367 368 int UDPSocketWin::SendTo(IOBuffer* buf, 369 int buf_len, 370 const IPEndPoint& address, 371 const CompletionCallback& callback) { 372 return SendToOrWrite(buf, buf_len, &address, callback); 373 } 374 375 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, 376 int buf_len, 377 const IPEndPoint* address, 378 const CompletionCallback& callback) { 379 DCHECK(CalledOnValidThread()); 380 DCHECK_NE(INVALID_SOCKET, socket_); 381 CHECK(write_callback_.is_null()); 382 DCHECK(!callback.is_null()); // Synchronous operation not supported. 383 DCHECK_GT(buf_len, 0); 384 DCHECK(!send_to_address_.get()); 385 386 int nwrite = InternalSendTo(buf, buf_len, address); 387 if (nwrite != ERR_IO_PENDING) 388 return nwrite; 389 390 if (address) 391 send_to_address_.reset(new IPEndPoint(*address)); 392 write_callback_ = callback; 393 return ERR_IO_PENDING; 394 } 395 396 int UDPSocketWin::Connect(const IPEndPoint& address) { 397 net_log_.BeginEvent(NetLog::TYPE_UDP_CONNECT, 398 CreateNetLogUDPConnectCallback(&address)); 399 int rv = InternalConnect(address); 400 if (rv != OK) 401 Close(); 402 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv); 403 return rv; 404 } 405 406 int UDPSocketWin::InternalConnect(const IPEndPoint& address) { 407 DCHECK(!is_connected()); 408 DCHECK(!remote_address_.get()); 409 int addr_family = address.GetSockAddrFamily(); 410 int rv = CreateSocket(addr_family); 411 if (rv < 0) 412 return rv; 413 414 if (bind_type_ == DatagramSocket::RANDOM_BIND) { 415 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s, 416 // representing INADDR_ANY or in6addr_any. 417 size_t addr_size = 418 addr_family == AF_INET ? kIPv4AddressSize : kIPv6AddressSize; 419 IPAddressNumber addr_any(addr_size); 420 rv = RandomBind(addr_any); 421 } 422 // else connect() does the DatagramSocket::DEFAULT_BIND 423 424 if (rv < 0) { 425 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketRandomBindErrorCode", -rv); 426 Close(); 427 return rv; 428 } 429 430 SockaddrStorage storage; 431 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 432 return ERR_ADDRESS_INVALID; 433 434 rv = connect(socket_, storage.addr, storage.addr_len); 435 if (rv < 0) { 436 // Close() may change the last error. Map it beforehand. 437 int result = MapSystemError(WSAGetLastError()); 438 Close(); 439 return result; 440 } 441 442 remote_address_.reset(new IPEndPoint(address)); 443 return rv; 444 } 445 446 int UDPSocketWin::Bind(const IPEndPoint& address) { 447 DCHECK(!is_connected()); 448 int rv = CreateSocket(address.GetSockAddrFamily()); 449 if (rv < 0) 450 return rv; 451 rv = SetSocketOptions(); 452 if (rv < 0) { 453 Close(); 454 return rv; 455 } 456 rv = DoBind(address); 457 if (rv < 0) { 458 Close(); 459 return rv; 460 } 461 local_address_.reset(); 462 return rv; 463 } 464 465 int UDPSocketWin::CreateSocket(int addr_family) { 466 addr_family_ = addr_family; 467 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); 468 if (socket_ == INVALID_SOCKET) 469 return MapSystemError(WSAGetLastError()); 470 core_ = new Core(this); 471 return OK; 472 } 473 474 int UDPSocketWin::SetReceiveBufferSize(int32 size) { 475 DCHECK(CalledOnValidThread()); 476 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, 477 reinterpret_cast<const char*>(&size), sizeof(size)); 478 if (rv != 0) 479 return MapSystemError(WSAGetLastError()); 480 481 // According to documentation, setsockopt may succeed, but we need to check 482 // the results via getsockopt to be sure it works on Windows. 483 int32 actual_size = 0; 484 int option_size = sizeof(actual_size); 485 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF, 486 reinterpret_cast<char*>(&actual_size), &option_size); 487 if (rv != 0) 488 return MapSystemError(WSAGetLastError()); 489 if (actual_size >= size) 490 return OK; 491 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer", 492 actual_size, 1000, 1000000, 50); 493 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE; 494 } 495 496 int UDPSocketWin::SetSendBufferSize(int32 size) { 497 DCHECK(CalledOnValidThread()); 498 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, 499 reinterpret_cast<const char*>(&size), sizeof(size)); 500 if (rv != 0) 501 return MapSystemError(WSAGetLastError()); 502 // According to documentation, setsockopt may succeed, but we need to check 503 // the results via getsockopt to be sure it works on Windows. 504 int32 actual_size = 0; 505 int option_size = sizeof(actual_size); 506 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF, 507 reinterpret_cast<char*>(&actual_size), &option_size); 508 if (rv != 0) 509 return MapSystemError(WSAGetLastError()); 510 if (actual_size >= size) 511 return OK; 512 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer", 513 actual_size, 1000, 1000000, 50); 514 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE; 515 } 516 517 void UDPSocketWin::AllowAddressReuse() { 518 DCHECK(CalledOnValidThread()); 519 DCHECK(!is_connected()); 520 521 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; 522 } 523 524 void UDPSocketWin::AllowBroadcast() { 525 DCHECK(CalledOnValidThread()); 526 DCHECK(!is_connected()); 527 528 socket_options_ |= SOCKET_OPTION_BROADCAST; 529 } 530 531 void UDPSocketWin::DoReadCallback(int rv) { 532 DCHECK_NE(rv, ERR_IO_PENDING); 533 DCHECK(!read_callback_.is_null()); 534 535 // since Run may result in Read being called, clear read_callback_ up front. 536 CompletionCallback c = read_callback_; 537 read_callback_.Reset(); 538 c.Run(rv); 539 } 540 541 void UDPSocketWin::DoWriteCallback(int rv) { 542 DCHECK_NE(rv, ERR_IO_PENDING); 543 DCHECK(!write_callback_.is_null()); 544 545 // since Run may result in Write being called, clear write_callback_ up front. 546 CompletionCallback c = write_callback_; 547 write_callback_.Reset(); 548 c.Run(rv); 549 } 550 551 void UDPSocketWin::DidCompleteRead() { 552 DWORD num_bytes, flags; 553 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, 554 &num_bytes, FALSE, &flags); 555 WSAResetEvent(core_->read_overlapped_.hEvent); 556 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); 557 // Convert address. 558 if (recv_from_address_ && result >= 0) { 559 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) 560 result = ERR_ADDRESS_INVALID; 561 } 562 LogRead(result, core_->read_iobuffer_->data()); 563 core_->read_iobuffer_ = NULL; 564 recv_from_address_ = NULL; 565 DoReadCallback(result); 566 } 567 568 void UDPSocketWin::LogRead(int result, const char* bytes) const { 569 if (result < 0) { 570 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); 571 return; 572 } 573 574 if (net_log_.IsLogging()) { 575 // Get address for logging, if |address| is NULL. 576 IPEndPoint address; 577 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); 578 net_log_.AddEvent( 579 NetLog::TYPE_UDP_BYTES_RECEIVED, 580 CreateNetLogUDPDataTranferCallback( 581 result, bytes, 582 is_address_valid ? &address : NULL)); 583 } 584 585 base::StatsCounter read_bytes("udp.read_bytes"); 586 read_bytes.Add(result); 587 } 588 589 void UDPSocketWin::DidCompleteWrite() { 590 DWORD num_bytes, flags; 591 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, 592 &num_bytes, FALSE, &flags); 593 WSAResetEvent(core_->write_overlapped_.hEvent); 594 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); 595 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); 596 597 send_to_address_.reset(); 598 core_->write_iobuffer_ = NULL; 599 DoWriteCallback(result); 600 } 601 602 void UDPSocketWin::LogWrite(int result, 603 const char* bytes, 604 const IPEndPoint* address) const { 605 if (result < 0) { 606 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); 607 return; 608 } 609 610 if (net_log_.IsLogging()) { 611 net_log_.AddEvent( 612 NetLog::TYPE_UDP_BYTES_SENT, 613 CreateNetLogUDPDataTranferCallback(result, bytes, address)); 614 } 615 616 base::StatsCounter write_bytes("udp.write_bytes"); 617 write_bytes.Add(result); 618 } 619 620 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, 621 IPEndPoint* address) { 622 DCHECK(!core_->read_iobuffer_); 623 SockaddrStorage& storage = core_->recv_addr_storage_; 624 storage.addr_len = sizeof(storage.addr_storage); 625 626 WSABUF read_buffer; 627 read_buffer.buf = buf->data(); 628 read_buffer.len = buf_len; 629 630 DWORD flags = 0; 631 DWORD num; 632 CHECK_NE(INVALID_SOCKET, socket_); 633 AssertEventNotSignaled(core_->read_overlapped_.hEvent); 634 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr, 635 &storage.addr_len, &core_->read_overlapped_, NULL); 636 if (rv == 0) { 637 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { 638 int result = num; 639 // Convert address. 640 if (address && result >= 0) { 641 if (!ReceiveAddressToIPEndpoint(address)) 642 result = ERR_ADDRESS_INVALID; 643 } 644 LogRead(result, buf->data()); 645 return result; 646 } 647 } else { 648 int os_error = WSAGetLastError(); 649 if (os_error != WSA_IO_PENDING) { 650 int result = MapSystemError(os_error); 651 LogRead(result, NULL); 652 return result; 653 } 654 } 655 core_->WatchForRead(); 656 core_->read_iobuffer_ = buf; 657 return ERR_IO_PENDING; 658 } 659 660 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, 661 const IPEndPoint* address) { 662 DCHECK(!core_->write_iobuffer_); 663 SockaddrStorage storage; 664 struct sockaddr* addr = storage.addr; 665 // Convert address. 666 if (!address) { 667 addr = NULL; 668 storage.addr_len = 0; 669 } else { 670 if (!address->ToSockAddr(addr, &storage.addr_len)) { 671 int result = ERR_ADDRESS_INVALID; 672 LogWrite(result, NULL, NULL); 673 return result; 674 } 675 } 676 677 WSABUF write_buffer; 678 write_buffer.buf = buf->data(); 679 write_buffer.len = buf_len; 680 681 DWORD flags = 0; 682 DWORD num; 683 AssertEventNotSignaled(core_->write_overlapped_.hEvent); 684 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, 685 addr, storage.addr_len, &core_->write_overlapped_, NULL); 686 if (rv == 0) { 687 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { 688 int result = num; 689 LogWrite(result, buf->data(), address); 690 return result; 691 } 692 } else { 693 int os_error = WSAGetLastError(); 694 if (os_error != WSA_IO_PENDING) { 695 int result = MapSystemError(os_error); 696 LogWrite(result, NULL, NULL); 697 return result; 698 } 699 } 700 701 core_->WatchForWrite(); 702 core_->write_iobuffer_ = buf; 703 return ERR_IO_PENDING; 704 } 705 706 int UDPSocketWin::SetSocketOptions() { 707 BOOL true_value = 1; 708 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { 709 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 710 reinterpret_cast<const char*>(&true_value), 711 sizeof(true_value)); 712 if (rv < 0) 713 return MapSystemError(WSAGetLastError()); 714 } 715 if (socket_options_ & SOCKET_OPTION_BROADCAST) { 716 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, 717 reinterpret_cast<const char*>(&true_value), 718 sizeof(true_value)); 719 if (rv < 0) 720 return MapSystemError(WSAGetLastError()); 721 } 722 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { 723 DWORD loop = 0; 724 int protocol_level = 725 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 726 int option = 727 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP; 728 int rv = setsockopt(socket_, protocol_level, option, 729 reinterpret_cast<const char*>(&loop), sizeof(loop)); 730 if (rv < 0) 731 return MapSystemError(WSAGetLastError()); 732 } 733 if (multicast_time_to_live_ != 1) { 734 DWORD hops = multicast_time_to_live_; 735 int protocol_level = 736 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 737 int option = 738 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS; 739 int rv = setsockopt(socket_, protocol_level, option, 740 reinterpret_cast<const char*>(&hops), sizeof(hops)); 741 if (rv < 0) 742 return MapSystemError(WSAGetLastError()); 743 } 744 if (multicast_interface_ != 0) { 745 switch (addr_family_) { 746 case AF_INET: { 747 in_addr address; 748 address.s_addr = htonl(multicast_interface_); 749 int rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_IF, 750 reinterpret_cast<const char*>(&address), 751 sizeof(address)); 752 if (rv) 753 return MapSystemError(WSAGetLastError()); 754 break; 755 } 756 case AF_INET6: { 757 uint32 interface_index = multicast_interface_; 758 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF, 759 reinterpret_cast<const char*>(&interface_index), 760 sizeof(interface_index)); 761 if (rv) 762 return MapSystemError(WSAGetLastError()); 763 break; 764 } 765 default: 766 NOTREACHED() << "Invalid address family"; 767 return ERR_ADDRESS_INVALID; 768 } 769 } 770 return OK; 771 } 772 773 int UDPSocketWin::DoBind(const IPEndPoint& address) { 774 SockaddrStorage storage; 775 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 776 return ERR_ADDRESS_INVALID; 777 int rv = bind(socket_, storage.addr, storage.addr_len); 778 if (rv == 0) 779 return OK; 780 int last_error = WSAGetLastError(); 781 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", last_error); 782 // Map some codes that are special to bind() separately. 783 // * WSAEACCES: If a port is already bound to a socket, WSAEACCES may be 784 // returned instead of WSAEADDRINUSE, depending on whether the socket 785 // option SO_REUSEADDR or SO_EXCLUSIVEADDRUSE is set and whether the 786 // conflicting socket is owned by a different user account. See the MSDN 787 // page "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" for the gory details. 788 if (last_error == WSAEACCES || last_error == WSAEADDRNOTAVAIL) 789 return ERR_ADDRESS_IN_USE; 790 return MapSystemError(last_error); 791 } 792 793 int UDPSocketWin::RandomBind(const IPAddressNumber& address) { 794 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); 795 796 for (int i = 0; i < kBindRetries; ++i) { 797 int rv = DoBind(IPEndPoint(address, 798 rand_int_cb_.Run(kPortStart, kPortEnd))); 799 if (rv == OK || rv != ERR_ADDRESS_IN_USE) 800 return rv; 801 } 802 return DoBind(IPEndPoint(address, 0)); 803 } 804 805 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { 806 SockaddrStorage& storage = core_->recv_addr_storage_; 807 return address->FromSockAddr(storage.addr, storage.addr_len); 808 } 809 810 int UDPSocketWin::JoinGroup( 811 const IPAddressNumber& group_address) const { 812 DCHECK(CalledOnValidThread()); 813 if (!is_connected()) 814 return ERR_SOCKET_NOT_CONNECTED; 815 816 switch (group_address.size()) { 817 case kIPv4AddressSize: { 818 if (addr_family_ != AF_INET) 819 return ERR_ADDRESS_INVALID; 820 ip_mreq mreq; 821 mreq.imr_interface.s_addr = htonl(multicast_interface_); 822 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); 823 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, 824 reinterpret_cast<const char*>(&mreq), 825 sizeof(mreq)); 826 if (rv) 827 return MapSystemError(WSAGetLastError()); 828 return OK; 829 } 830 case kIPv6AddressSize: { 831 if (addr_family_ != AF_INET6) 832 return ERR_ADDRESS_INVALID; 833 ipv6_mreq mreq; 834 mreq.ipv6mr_interface = multicast_interface_; 835 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); 836 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, 837 reinterpret_cast<const char*>(&mreq), 838 sizeof(mreq)); 839 if (rv) 840 return MapSystemError(WSAGetLastError()); 841 return OK; 842 } 843 default: 844 NOTREACHED() << "Invalid address family"; 845 return ERR_ADDRESS_INVALID; 846 } 847 } 848 849 int UDPSocketWin::LeaveGroup( 850 const IPAddressNumber& group_address) const { 851 DCHECK(CalledOnValidThread()); 852 if (!is_connected()) 853 return ERR_SOCKET_NOT_CONNECTED; 854 855 switch (group_address.size()) { 856 case kIPv4AddressSize: { 857 if (addr_family_ != AF_INET) 858 return ERR_ADDRESS_INVALID; 859 ip_mreq mreq; 860 mreq.imr_interface.s_addr = htonl(multicast_interface_); 861 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); 862 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, 863 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); 864 if (rv) 865 return MapSystemError(WSAGetLastError()); 866 return OK; 867 } 868 case kIPv6AddressSize: { 869 if (addr_family_ != AF_INET6) 870 return ERR_ADDRESS_INVALID; 871 ipv6_mreq mreq; 872 mreq.ipv6mr_interface = multicast_interface_; 873 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); 874 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, 875 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); 876 if (rv) 877 return MapSystemError(WSAGetLastError()); 878 return OK; 879 } 880 default: 881 NOTREACHED() << "Invalid address family"; 882 return ERR_ADDRESS_INVALID; 883 } 884 } 885 886 int UDPSocketWin::SetMulticastInterface(uint32 interface_index) { 887 DCHECK(CalledOnValidThread()); 888 if (is_connected()) 889 return ERR_SOCKET_IS_CONNECTED; 890 multicast_interface_ = interface_index; 891 return OK; 892 } 893 894 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) { 895 DCHECK(CalledOnValidThread()); 896 if (is_connected()) 897 return ERR_SOCKET_IS_CONNECTED; 898 899 if (time_to_live < 0 || time_to_live > 255) 900 return ERR_INVALID_ARGUMENT; 901 multicast_time_to_live_ = time_to_live; 902 return OK; 903 } 904 905 int UDPSocketWin::SetMulticastLoopbackMode(bool loopback) { 906 DCHECK(CalledOnValidThread()); 907 if (is_connected()) 908 return ERR_SOCKET_IS_CONNECTED; 909 910 if (loopback) 911 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP; 912 else 913 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP; 914 return OK; 915 } 916 917 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) { 918 if (dscp == DSCP_NO_CHANGE) { 919 return OK; 920 } 921 922 if (!is_connected()) 923 return ERR_SOCKET_NOT_CONNECTED; 924 925 QwaveAPI& qos(QwaveAPI::Get()); 926 927 if (!qos.qwave_supported()) 928 return ERROR_NOT_SUPPORTED; 929 930 if (qos_handle_ == NULL) { 931 QOS_VERSION version; 932 version.MajorVersion = 1; 933 version.MinorVersion = 0; 934 qos.CreateHandle(&version, &qos_handle_); 935 if (qos_handle_ == NULL) 936 return ERROR_NOT_SUPPORTED; 937 } 938 939 QOS_TRAFFIC_TYPE traffic_type = QOSTrafficTypeBestEffort; 940 switch (dscp) { 941 case DSCP_CS0: 942 traffic_type = QOSTrafficTypeBestEffort; 943 break; 944 case DSCP_CS1: 945 traffic_type = QOSTrafficTypeBackground; 946 break; 947 case DSCP_AF11: 948 case DSCP_AF12: 949 case DSCP_AF13: 950 case DSCP_CS2: 951 case DSCP_AF21: 952 case DSCP_AF22: 953 case DSCP_AF23: 954 case DSCP_CS3: 955 case DSCP_AF31: 956 case DSCP_AF32: 957 case DSCP_AF33: 958 case DSCP_CS4: 959 traffic_type = QOSTrafficTypeExcellentEffort; 960 break; 961 case DSCP_AF41: 962 case DSCP_AF42: 963 case DSCP_AF43: 964 case DSCP_CS5: 965 traffic_type = QOSTrafficTypeAudioVideo; 966 break; 967 case DSCP_EF: 968 case DSCP_CS6: 969 traffic_type = QOSTrafficTypeVoice; 970 break; 971 case DSCP_CS7: 972 traffic_type = QOSTrafficTypeControl; 973 break; 974 case DSCP_NO_CHANGE: 975 NOTREACHED(); 976 break; 977 } 978 if (qos_flow_id_ != 0) { 979 qos.RemoveSocketFromFlow(qos_handle_, NULL, qos_flow_id_, 0); 980 qos_flow_id_ = 0; 981 } 982 if (!qos.AddSocketToFlow(qos_handle_, 983 socket_, 984 NULL, 985 traffic_type, 986 QOS_NON_ADAPTIVE_FLOW, 987 &qos_flow_id_)) { 988 DWORD err = GetLastError(); 989 if (err == ERROR_DEVICE_REINITIALIZATION_NEEDED) { 990 qos.CloseHandle(qos_handle_); 991 qos_flow_id_ = 0; 992 qos_handle_ = 0; 993 } 994 return MapSystemError(err); 995 } 996 // This requires admin rights, and may fail, if so we ignore it 997 // as AddSocketToFlow should still do *approximately* the right thing. 998 DWORD buf = dscp; 999 qos.SetFlow(qos_handle_, 1000 qos_flow_id_, 1001 QOSSetOutgoingDSCPValue, 1002 sizeof(buf), 1003 &buf, 1004 0, 1005 NULL); 1006 1007 return OK; 1008 } 1009 1010 void UDPSocketWin::DetachFromThread() { 1011 base::NonThreadSafe::DetachFromThread(); 1012 } 1013 1014 } // namespace net 1015