| 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/logging.h" | 10 #include "base/logging.h" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 | 99 |
| 100 // |read_watcher_| watches for events from Read(). | 100 // |read_watcher_| watches for events from Read(). |
| 101 base::win::ObjectWatcher read_watcher_; | 101 base::win::ObjectWatcher read_watcher_; |
| 102 // |write_watcher_| watches for events from Write(); | 102 // |write_watcher_| watches for events from Write(); |
| 103 base::win::ObjectWatcher write_watcher_; | 103 base::win::ObjectWatcher write_watcher_; |
| 104 | 104 |
| 105 DISALLOW_COPY_AND_ASSIGN(Core); | 105 DISALLOW_COPY_AND_ASSIGN(Core); |
| 106 }; | 106 }; |
| 107 | 107 |
| 108 UDPSocketWin::Core::Core(UDPSocketWin* socket) | 108 UDPSocketWin::Core::Core(UDPSocketWin* socket) |
| 109 : socket_(socket), | 109 : socket_(socket), reader_(this), writer_(this) { |
| 110 reader_(this), | |
| 111 writer_(this) { | |
| 112 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 110 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
| 113 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 111 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
| 114 | 112 |
| 115 read_overlapped_.hEvent = WSACreateEvent(); | 113 read_overlapped_.hEvent = WSACreateEvent(); |
| 116 write_overlapped_.hEvent = WSACreateEvent(); | 114 write_overlapped_.hEvent = WSACreateEvent(); |
| 117 } | 115 } |
| 118 | 116 |
| 119 UDPSocketWin::Core::~Core() { | 117 UDPSocketWin::Core::~Core() { |
| 120 // Make sure the message loop is not watching this object anymore. | 118 // Make sure the message loop is not watching this object anymore. |
| 121 read_watcher_.StopWatching(); | 119 read_watcher_.StopWatching(); |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 addr_family_ = addr_family; | 381 addr_family_ = addr_family; |
| 384 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); | 382 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); |
| 385 if (socket_ == INVALID_SOCKET) | 383 if (socket_ == INVALID_SOCKET) |
| 386 return MapSystemError(WSAGetLastError()); | 384 return MapSystemError(WSAGetLastError()); |
| 387 core_ = new Core(this); | 385 core_ = new Core(this); |
| 388 return OK; | 386 return OK; |
| 389 } | 387 } |
| 390 | 388 |
| 391 int UDPSocketWin::SetReceiveBufferSize(int32 size) { | 389 int UDPSocketWin::SetReceiveBufferSize(int32 size) { |
| 392 DCHECK(CalledOnValidThread()); | 390 DCHECK(CalledOnValidThread()); |
| 393 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, | 391 int rv = setsockopt(socket_, |
| 394 reinterpret_cast<const char*>(&size), sizeof(size)); | 392 SOL_SOCKET, |
| 393 SO_RCVBUF, |
| 394 reinterpret_cast<const char*>(&size), |
| 395 sizeof(size)); |
| 395 if (rv != 0) | 396 if (rv != 0) |
| 396 return MapSystemError(WSAGetLastError()); | 397 return MapSystemError(WSAGetLastError()); |
| 397 | 398 |
| 398 // According to documentation, setsockopt may succeed, but we need to check | 399 // According to documentation, setsockopt may succeed, but we need to check |
| 399 // the results via getsockopt to be sure it works on Windows. | 400 // the results via getsockopt to be sure it works on Windows. |
| 400 int32 actual_size = 0; | 401 int32 actual_size = 0; |
| 401 int option_size = sizeof(actual_size); | 402 int option_size = sizeof(actual_size); |
| 402 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF, | 403 rv = getsockopt(socket_, |
| 403 reinterpret_cast<char*>(&actual_size), &option_size); | 404 SOL_SOCKET, |
| 405 SO_RCVBUF, |
| 406 reinterpret_cast<char*>(&actual_size), |
| 407 &option_size); |
| 404 if (rv != 0) | 408 if (rv != 0) |
| 405 return MapSystemError(WSAGetLastError()); | 409 return MapSystemError(WSAGetLastError()); |
| 406 if (actual_size >= size) | 410 if (actual_size >= size) |
| 407 return OK; | 411 return OK; |
| 408 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer", | 412 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 409 actual_size, 1000, 1000000, 50); | 413 "Net.SocketUnchangeableReceiveBuffer", actual_size, 1000, 1000000, 50); |
| 410 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE; | 414 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE; |
| 411 } | 415 } |
| 412 | 416 |
| 413 int UDPSocketWin::SetSendBufferSize(int32 size) { | 417 int UDPSocketWin::SetSendBufferSize(int32 size) { |
| 414 DCHECK(CalledOnValidThread()); | 418 DCHECK(CalledOnValidThread()); |
| 415 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 419 int rv = setsockopt(socket_, |
| 416 reinterpret_cast<const char*>(&size), sizeof(size)); | 420 SOL_SOCKET, |
| 421 SO_SNDBUF, |
| 422 reinterpret_cast<const char*>(&size), |
| 423 sizeof(size)); |
| 417 if (rv != 0) | 424 if (rv != 0) |
| 418 return MapSystemError(WSAGetLastError()); | 425 return MapSystemError(WSAGetLastError()); |
| 419 // According to documentation, setsockopt may succeed, but we need to check | 426 // According to documentation, setsockopt may succeed, but we need to check |
| 420 // the results via getsockopt to be sure it works on Windows. | 427 // the results via getsockopt to be sure it works on Windows. |
| 421 int32 actual_size = 0; | 428 int32 actual_size = 0; |
| 422 int option_size = sizeof(actual_size); | 429 int option_size = sizeof(actual_size); |
| 423 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 430 rv = getsockopt(socket_, |
| 424 reinterpret_cast<char*>(&actual_size), &option_size); | 431 SOL_SOCKET, |
| 432 SO_SNDBUF, |
| 433 reinterpret_cast<char*>(&actual_size), |
| 434 &option_size); |
| 425 if (rv != 0) | 435 if (rv != 0) |
| 426 return MapSystemError(WSAGetLastError()); | 436 return MapSystemError(WSAGetLastError()); |
| 427 if (actual_size >= size) | 437 if (actual_size >= size) |
| 428 return OK; | 438 return OK; |
| 429 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer", | 439 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 430 actual_size, 1000, 1000000, 50); | 440 "Net.SocketUnchangeableSendBuffer", actual_size, 1000, 1000000, 50); |
| 431 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE; | 441 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE; |
| 432 } | 442 } |
| 433 | 443 |
| 434 void UDPSocketWin::AllowAddressReuse() { | 444 void UDPSocketWin::AllowAddressReuse() { |
| 435 DCHECK(CalledOnValidThread()); | 445 DCHECK(CalledOnValidThread()); |
| 436 DCHECK(!is_connected()); | 446 DCHECK(!is_connected()); |
| 437 | 447 |
| 438 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; | 448 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; |
| 439 } | 449 } |
| 440 | 450 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 460 DCHECK(!write_callback_.is_null()); | 470 DCHECK(!write_callback_.is_null()); |
| 461 | 471 |
| 462 // since Run may result in Write being called, clear write_callback_ up front. | 472 // since Run may result in Write being called, clear write_callback_ up front. |
| 463 CompletionCallback c = write_callback_; | 473 CompletionCallback c = write_callback_; |
| 464 write_callback_.Reset(); | 474 write_callback_.Reset(); |
| 465 c.Run(rv); | 475 c.Run(rv); |
| 466 } | 476 } |
| 467 | 477 |
| 468 void UDPSocketWin::DidCompleteRead() { | 478 void UDPSocketWin::DidCompleteRead() { |
| 469 DWORD num_bytes, flags; | 479 DWORD num_bytes, flags; |
| 470 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, | 480 BOOL ok = WSAGetOverlappedResult( |
| 471 &num_bytes, FALSE, &flags); | 481 socket_, &core_->read_overlapped_, &num_bytes, FALSE, &flags); |
| 472 WSAResetEvent(core_->read_overlapped_.hEvent); | 482 WSAResetEvent(core_->read_overlapped_.hEvent); |
| 473 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 483 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
| 474 // Convert address. | 484 // Convert address. |
| 475 if (recv_from_address_ && result >= 0) { | 485 if (recv_from_address_ && result >= 0) { |
| 476 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) | 486 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) |
| 477 result = ERR_ADDRESS_INVALID; | 487 result = ERR_ADDRESS_INVALID; |
| 478 } | 488 } |
| 479 LogRead(result, core_->read_iobuffer_->data()); | 489 LogRead(result, core_->read_iobuffer_->data()); |
| 480 core_->read_iobuffer_ = NULL; | 490 core_->read_iobuffer_ = NULL; |
| 481 recv_from_address_ = NULL; | 491 recv_from_address_ = NULL; |
| 482 DoReadCallback(result); | 492 DoReadCallback(result); |
| 483 } | 493 } |
| 484 | 494 |
| 485 void UDPSocketWin::LogRead(int result, const char* bytes) const { | 495 void UDPSocketWin::LogRead(int result, const char* bytes) const { |
| 486 if (result < 0) { | 496 if (result < 0) { |
| 487 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); | 497 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); |
| 488 return; | 498 return; |
| 489 } | 499 } |
| 490 | 500 |
| 491 if (net_log_.IsLogging()) { | 501 if (net_log_.IsLogging()) { |
| 492 // Get address for logging, if |address| is NULL. | 502 // Get address for logging, if |address| is NULL. |
| 493 IPEndPoint address; | 503 IPEndPoint address; |
| 494 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); | 504 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); |
| 495 net_log_.AddEvent( | 505 net_log_.AddEvent(NetLog::TYPE_UDP_BYTES_RECEIVED, |
| 496 NetLog::TYPE_UDP_BYTES_RECEIVED, | 506 CreateNetLogUDPDataTranferCallback( |
| 497 CreateNetLogUDPDataTranferCallback( | 507 result, bytes, is_address_valid ? &address : NULL)); |
| 498 result, bytes, | |
| 499 is_address_valid ? &address : NULL)); | |
| 500 } | 508 } |
| 501 | 509 |
| 502 base::StatsCounter read_bytes("udp.read_bytes"); | 510 base::StatsCounter read_bytes("udp.read_bytes"); |
| 503 read_bytes.Add(result); | 511 read_bytes.Add(result); |
| 504 } | 512 } |
| 505 | 513 |
| 506 void UDPSocketWin::DidCompleteWrite() { | 514 void UDPSocketWin::DidCompleteWrite() { |
| 507 DWORD num_bytes, flags; | 515 DWORD num_bytes, flags; |
| 508 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 516 BOOL ok = WSAGetOverlappedResult( |
| 509 &num_bytes, FALSE, &flags); | 517 socket_, &core_->write_overlapped_, &num_bytes, FALSE, &flags); |
| 510 WSAResetEvent(core_->write_overlapped_.hEvent); | 518 WSAResetEvent(core_->write_overlapped_.hEvent); |
| 511 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 519 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
| 512 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); | 520 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); |
| 513 | 521 |
| 514 send_to_address_.reset(); | 522 send_to_address_.reset(); |
| 515 core_->write_iobuffer_ = NULL; | 523 core_->write_iobuffer_ = NULL; |
| 516 DoWriteCallback(result); | 524 DoWriteCallback(result); |
| 517 } | 525 } |
| 518 | 526 |
| 519 void UDPSocketWin::LogWrite(int result, | 527 void UDPSocketWin::LogWrite(int result, |
| 520 const char* bytes, | 528 const char* bytes, |
| 521 const IPEndPoint* address) const { | 529 const IPEndPoint* address) const { |
| 522 if (result < 0) { | 530 if (result < 0) { |
| 523 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); | 531 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); |
| 524 return; | 532 return; |
| 525 } | 533 } |
| 526 | 534 |
| 527 if (net_log_.IsLogging()) { | 535 if (net_log_.IsLogging()) { |
| 528 net_log_.AddEvent( | 536 net_log_.AddEvent( |
| 529 NetLog::TYPE_UDP_BYTES_SENT, | 537 NetLog::TYPE_UDP_BYTES_SENT, |
| 530 CreateNetLogUDPDataTranferCallback(result, bytes, address)); | 538 CreateNetLogUDPDataTranferCallback(result, bytes, address)); |
| 531 } | 539 } |
| 532 | 540 |
| 533 base::StatsCounter write_bytes("udp.write_bytes"); | 541 base::StatsCounter write_bytes("udp.write_bytes"); |
| 534 write_bytes.Add(result); | 542 write_bytes.Add(result); |
| 535 } | 543 } |
| 536 | 544 |
| 537 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, | 545 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, |
| 546 int buf_len, |
| 538 IPEndPoint* address) { | 547 IPEndPoint* address) { |
| 539 DCHECK(!core_->read_iobuffer_); | 548 DCHECK(!core_->read_iobuffer_); |
| 540 SockaddrStorage& storage = core_->recv_addr_storage_; | 549 SockaddrStorage& storage = core_->recv_addr_storage_; |
| 541 storage.addr_len = sizeof(storage.addr_storage); | 550 storage.addr_len = sizeof(storage.addr_storage); |
| 542 | 551 |
| 543 WSABUF read_buffer; | 552 WSABUF read_buffer; |
| 544 read_buffer.buf = buf->data(); | 553 read_buffer.buf = buf->data(); |
| 545 read_buffer.len = buf_len; | 554 read_buffer.len = buf_len; |
| 546 | 555 |
| 547 DWORD flags = 0; | 556 DWORD flags = 0; |
| 548 DWORD num; | 557 DWORD num; |
| 549 CHECK_NE(INVALID_SOCKET, socket_); | 558 CHECK_NE(INVALID_SOCKET, socket_); |
| 550 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | 559 AssertEventNotSignaled(core_->read_overlapped_.hEvent); |
| 551 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr, | 560 int rv = WSARecvFrom(socket_, |
| 552 &storage.addr_len, &core_->read_overlapped_, NULL); | 561 &read_buffer, |
| 562 1, |
| 563 &num, |
| 564 &flags, |
| 565 storage.addr, |
| 566 &storage.addr_len, |
| 567 &core_->read_overlapped_, |
| 568 NULL); |
| 553 if (rv == 0) { | 569 if (rv == 0) { |
| 554 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | 570 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { |
| 555 int result = num; | 571 int result = num; |
| 556 // Convert address. | 572 // Convert address. |
| 557 if (address && result >= 0) { | 573 if (address && result >= 0) { |
| 558 if (!ReceiveAddressToIPEndpoint(address)) | 574 if (!ReceiveAddressToIPEndpoint(address)) |
| 559 result = ERR_ADDRESS_INVALID; | 575 result = ERR_ADDRESS_INVALID; |
| 560 } | 576 } |
| 561 LogRead(result, buf->data()); | 577 LogRead(result, buf->data()); |
| 562 return result; | 578 return result; |
| 563 } | 579 } |
| 564 } else { | 580 } else { |
| 565 int os_error = WSAGetLastError(); | 581 int os_error = WSAGetLastError(); |
| 566 if (os_error != WSA_IO_PENDING) { | 582 if (os_error != WSA_IO_PENDING) { |
| 567 int result = MapSystemError(os_error); | 583 int result = MapSystemError(os_error); |
| 568 LogRead(result, NULL); | 584 LogRead(result, NULL); |
| 569 return result; | 585 return result; |
| 570 } | 586 } |
| 571 } | 587 } |
| 572 core_->WatchForRead(); | 588 core_->WatchForRead(); |
| 573 core_->read_iobuffer_ = buf; | 589 core_->read_iobuffer_ = buf; |
| 574 return ERR_IO_PENDING; | 590 return ERR_IO_PENDING; |
| 575 } | 591 } |
| 576 | 592 |
| 577 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, | 593 int UDPSocketWin::InternalSendTo(IOBuffer* buf, |
| 594 int buf_len, |
| 578 const IPEndPoint* address) { | 595 const IPEndPoint* address) { |
| 579 DCHECK(!core_->write_iobuffer_); | 596 DCHECK(!core_->write_iobuffer_); |
| 580 SockaddrStorage storage; | 597 SockaddrStorage storage; |
| 581 struct sockaddr* addr = storage.addr; | 598 struct sockaddr* addr = storage.addr; |
| 582 // Convert address. | 599 // Convert address. |
| 583 if (!address) { | 600 if (!address) { |
| 584 addr = NULL; | 601 addr = NULL; |
| 585 storage.addr_len = 0; | 602 storage.addr_len = 0; |
| 586 } else { | 603 } else { |
| 587 if (!address->ToSockAddr(addr, &storage.addr_len)) { | 604 if (!address->ToSockAddr(addr, &storage.addr_len)) { |
| 588 int result = ERR_ADDRESS_INVALID; | 605 int result = ERR_ADDRESS_INVALID; |
| 589 LogWrite(result, NULL, NULL); | 606 LogWrite(result, NULL, NULL); |
| 590 return result; | 607 return result; |
| 591 } | 608 } |
| 592 } | 609 } |
| 593 | 610 |
| 594 WSABUF write_buffer; | 611 WSABUF write_buffer; |
| 595 write_buffer.buf = buf->data(); | 612 write_buffer.buf = buf->data(); |
| 596 write_buffer.len = buf_len; | 613 write_buffer.len = buf_len; |
| 597 | 614 |
| 598 DWORD flags = 0; | 615 DWORD flags = 0; |
| 599 DWORD num; | 616 DWORD num; |
| 600 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | 617 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
| 601 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, | 618 int rv = WSASendTo(socket_, |
| 602 addr, storage.addr_len, &core_->write_overlapped_, NULL); | 619 &write_buffer, |
| 620 1, |
| 621 &num, |
| 622 flags, |
| 623 addr, |
| 624 storage.addr_len, |
| 625 &core_->write_overlapped_, |
| 626 NULL); |
| 603 if (rv == 0) { | 627 if (rv == 0) { |
| 604 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | 628 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
| 605 int result = num; | 629 int result = num; |
| 606 LogWrite(result, buf->data(), address); | 630 LogWrite(result, buf->data(), address); |
| 607 return result; | 631 return result; |
| 608 } | 632 } |
| 609 } else { | 633 } else { |
| 610 int os_error = WSAGetLastError(); | 634 int os_error = WSAGetLastError(); |
| 611 if (os_error != WSA_IO_PENDING) { | 635 if (os_error != WSA_IO_PENDING) { |
| 612 int result = MapSystemError(os_error); | 636 int result = MapSystemError(os_error); |
| 613 LogWrite(result, NULL, NULL); | 637 LogWrite(result, NULL, NULL); |
| 614 return result; | 638 return result; |
| 615 } | 639 } |
| 616 } | 640 } |
| 617 | 641 |
| 618 core_->WatchForWrite(); | 642 core_->WatchForWrite(); |
| 619 core_->write_iobuffer_ = buf; | 643 core_->write_iobuffer_ = buf; |
| 620 return ERR_IO_PENDING; | 644 return ERR_IO_PENDING; |
| 621 } | 645 } |
| 622 | 646 |
| 623 int UDPSocketWin::SetSocketOptions() { | 647 int UDPSocketWin::SetSocketOptions() { |
| 624 BOOL true_value = 1; | 648 BOOL true_value = 1; |
| 625 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { | 649 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { |
| 626 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, | 650 int rv = setsockopt(socket_, |
| 651 SOL_SOCKET, |
| 652 SO_REUSEADDR, |
| 627 reinterpret_cast<const char*>(&true_value), | 653 reinterpret_cast<const char*>(&true_value), |
| 628 sizeof(true_value)); | 654 sizeof(true_value)); |
| 629 if (rv < 0) | 655 if (rv < 0) |
| 630 return MapSystemError(WSAGetLastError()); | 656 return MapSystemError(WSAGetLastError()); |
| 631 } | 657 } |
| 632 if (socket_options_ & SOCKET_OPTION_BROADCAST) { | 658 if (socket_options_ & SOCKET_OPTION_BROADCAST) { |
| 633 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, | 659 int rv = setsockopt(socket_, |
| 660 SOL_SOCKET, |
| 661 SO_BROADCAST, |
| 634 reinterpret_cast<const char*>(&true_value), | 662 reinterpret_cast<const char*>(&true_value), |
| 635 sizeof(true_value)); | 663 sizeof(true_value)); |
| 636 if (rv < 0) | 664 if (rv < 0) |
| 637 return MapSystemError(WSAGetLastError()); | 665 return MapSystemError(WSAGetLastError()); |
| 638 } | 666 } |
| 639 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { | 667 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { |
| 640 DWORD loop = 0; | 668 DWORD loop = 0; |
| 641 int protocol_level = | 669 int protocol_level = addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
| 642 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | |
| 643 int option = | 670 int option = |
| 644 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP; | 671 addr_family_ == AF_INET ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; |
| 645 int rv = setsockopt(socket_, protocol_level, option, | 672 int rv = setsockopt(socket_, |
| 646 reinterpret_cast<const char*>(&loop), sizeof(loop)); | 673 protocol_level, |
| 674 option, |
| 675 reinterpret_cast<const char*>(&loop), |
| 676 sizeof(loop)); |
| 647 if (rv < 0) | 677 if (rv < 0) |
| 648 return MapSystemError(WSAGetLastError()); | 678 return MapSystemError(WSAGetLastError()); |
| 649 } | 679 } |
| 650 if (multicast_time_to_live_ != 1) { | 680 if (multicast_time_to_live_ != 1) { |
| 651 DWORD hops = multicast_time_to_live_; | 681 DWORD hops = multicast_time_to_live_; |
| 652 int protocol_level = | 682 int protocol_level = addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
| 653 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | |
| 654 int option = | 683 int option = |
| 655 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS; | 684 addr_family_ == AF_INET ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; |
| 656 int rv = setsockopt(socket_, protocol_level, option, | 685 int rv = setsockopt(socket_, |
| 657 reinterpret_cast<const char*>(&hops), sizeof(hops)); | 686 protocol_level, |
| 687 option, |
| 688 reinterpret_cast<const char*>(&hops), |
| 689 sizeof(hops)); |
| 658 if (rv < 0) | 690 if (rv < 0) |
| 659 return MapSystemError(WSAGetLastError()); | 691 return MapSystemError(WSAGetLastError()); |
| 660 } | 692 } |
| 661 if (multicast_interface_ != 0) { | 693 if (multicast_interface_ != 0) { |
| 662 switch (addr_family_) { | 694 switch (addr_family_) { |
| 663 case AF_INET: { | 695 case AF_INET: { |
| 664 in_addr address; | 696 in_addr address; |
| 665 address.s_addr = htonl(multicast_interface_); | 697 address.s_addr = htonl(multicast_interface_); |
| 666 int rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_IF, | 698 int rv = setsockopt(socket_, |
| 699 IPPROTO_IP, |
| 700 IP_MULTICAST_IF, |
| 667 reinterpret_cast<const char*>(&address), | 701 reinterpret_cast<const char*>(&address), |
| 668 sizeof(address)); | 702 sizeof(address)); |
| 669 if (rv) | 703 if (rv) |
| 670 return MapSystemError(WSAGetLastError()); | 704 return MapSystemError(WSAGetLastError()); |
| 671 break; | 705 break; |
| 672 } | 706 } |
| 673 case AF_INET6: { | 707 case AF_INET6: { |
| 674 uint32 interface_index = multicast_interface_; | 708 uint32 interface_index = multicast_interface_; |
| 675 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF, | 709 int rv = setsockopt(socket_, |
| 710 IPPROTO_IPV6, |
| 711 IPV6_MULTICAST_IF, |
| 676 reinterpret_cast<const char*>(&interface_index), | 712 reinterpret_cast<const char*>(&interface_index), |
| 677 sizeof(interface_index)); | 713 sizeof(interface_index)); |
| 678 if (rv) | 714 if (rv) |
| 679 return MapSystemError(WSAGetLastError()); | 715 return MapSystemError(WSAGetLastError()); |
| 680 break; | 716 break; |
| 681 } | 717 } |
| 682 default: | 718 default: |
| 683 NOTREACHED() << "Invalid address family"; | 719 NOTREACHED() << "Invalid address family"; |
| 684 return ERR_ADDRESS_INVALID; | 720 return ERR_ADDRESS_INVALID; |
| 685 } | 721 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 704 // page "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" for the gory details. | 740 // page "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" for the gory details. |
| 705 if (last_error == WSAEACCES || last_error == WSAEADDRNOTAVAIL) | 741 if (last_error == WSAEACCES || last_error == WSAEADDRNOTAVAIL) |
| 706 return ERR_ADDRESS_IN_USE; | 742 return ERR_ADDRESS_IN_USE; |
| 707 return MapSystemError(last_error); | 743 return MapSystemError(last_error); |
| 708 } | 744 } |
| 709 | 745 |
| 710 int UDPSocketWin::RandomBind(const IPAddressNumber& address) { | 746 int UDPSocketWin::RandomBind(const IPAddressNumber& address) { |
| 711 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); | 747 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); |
| 712 | 748 |
| 713 for (int i = 0; i < kBindRetries; ++i) { | 749 for (int i = 0; i < kBindRetries; ++i) { |
| 714 int rv = DoBind(IPEndPoint(address, | 750 int rv = |
| 715 rand_int_cb_.Run(kPortStart, kPortEnd))); | 751 DoBind(IPEndPoint(address, rand_int_cb_.Run(kPortStart, kPortEnd))); |
| 716 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 752 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
| 717 return rv; | 753 return rv; |
| 718 } | 754 } |
| 719 return DoBind(IPEndPoint(address, 0)); | 755 return DoBind(IPEndPoint(address, 0)); |
| 720 } | 756 } |
| 721 | 757 |
| 722 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | 758 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
| 723 SockaddrStorage& storage = core_->recv_addr_storage_; | 759 SockaddrStorage& storage = core_->recv_addr_storage_; |
| 724 return address->FromSockAddr(storage.addr, storage.addr_len); | 760 return address->FromSockAddr(storage.addr, storage.addr_len); |
| 725 } | 761 } |
| 726 | 762 |
| 727 int UDPSocketWin::JoinGroup( | 763 int UDPSocketWin::JoinGroup(const IPAddressNumber& group_address) const { |
| 728 const IPAddressNumber& group_address) const { | |
| 729 DCHECK(CalledOnValidThread()); | 764 DCHECK(CalledOnValidThread()); |
| 730 if (!is_connected()) | 765 if (!is_connected()) |
| 731 return ERR_SOCKET_NOT_CONNECTED; | 766 return ERR_SOCKET_NOT_CONNECTED; |
| 732 | 767 |
| 733 switch (group_address.size()) { | 768 switch (group_address.size()) { |
| 734 case kIPv4AddressSize: { | 769 case kIPv4AddressSize: { |
| 735 if (addr_family_ != AF_INET) | 770 if (addr_family_ != AF_INET) |
| 736 return ERR_ADDRESS_INVALID; | 771 return ERR_ADDRESS_INVALID; |
| 737 ip_mreq mreq; | 772 ip_mreq mreq; |
| 738 mreq.imr_interface.s_addr = htonl(multicast_interface_); | 773 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
| 739 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); | 774 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
| 740 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, | 775 int rv = setsockopt(socket_, |
| 776 IPPROTO_IP, |
| 777 IP_ADD_MEMBERSHIP, |
| 741 reinterpret_cast<const char*>(&mreq), | 778 reinterpret_cast<const char*>(&mreq), |
| 742 sizeof(mreq)); | 779 sizeof(mreq)); |
| 743 if (rv) | 780 if (rv) |
| 744 return MapSystemError(WSAGetLastError()); | 781 return MapSystemError(WSAGetLastError()); |
| 745 return OK; | 782 return OK; |
| 746 } | 783 } |
| 747 case kIPv6AddressSize: { | 784 case kIPv6AddressSize: { |
| 748 if (addr_family_ != AF_INET6) | 785 if (addr_family_ != AF_INET6) |
| 749 return ERR_ADDRESS_INVALID; | 786 return ERR_ADDRESS_INVALID; |
| 750 ipv6_mreq mreq; | 787 ipv6_mreq mreq; |
| 751 mreq.ipv6mr_interface = multicast_interface_; | 788 mreq.ipv6mr_interface = multicast_interface_; |
| 752 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); | 789 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
| 753 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, | 790 int rv = setsockopt(socket_, |
| 791 IPPROTO_IPV6, |
| 792 IPV6_ADD_MEMBERSHIP, |
| 754 reinterpret_cast<const char*>(&mreq), | 793 reinterpret_cast<const char*>(&mreq), |
| 755 sizeof(mreq)); | 794 sizeof(mreq)); |
| 756 if (rv) | 795 if (rv) |
| 757 return MapSystemError(WSAGetLastError()); | 796 return MapSystemError(WSAGetLastError()); |
| 758 return OK; | 797 return OK; |
| 759 } | 798 } |
| 760 default: | 799 default: |
| 761 NOTREACHED() << "Invalid address family"; | 800 NOTREACHED() << "Invalid address family"; |
| 762 return ERR_ADDRESS_INVALID; | 801 return ERR_ADDRESS_INVALID; |
| 763 } | 802 } |
| 764 } | 803 } |
| 765 | 804 |
| 766 int UDPSocketWin::LeaveGroup( | 805 int UDPSocketWin::LeaveGroup(const IPAddressNumber& group_address) const { |
| 767 const IPAddressNumber& group_address) const { | |
| 768 DCHECK(CalledOnValidThread()); | 806 DCHECK(CalledOnValidThread()); |
| 769 if (!is_connected()) | 807 if (!is_connected()) |
| 770 return ERR_SOCKET_NOT_CONNECTED; | 808 return ERR_SOCKET_NOT_CONNECTED; |
| 771 | 809 |
| 772 switch (group_address.size()) { | 810 switch (group_address.size()) { |
| 773 case kIPv4AddressSize: { | 811 case kIPv4AddressSize: { |
| 774 if (addr_family_ != AF_INET) | 812 if (addr_family_ != AF_INET) |
| 775 return ERR_ADDRESS_INVALID; | 813 return ERR_ADDRESS_INVALID; |
| 776 ip_mreq mreq; | 814 ip_mreq mreq; |
| 777 mreq.imr_interface.s_addr = htonl(multicast_interface_); | 815 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
| 778 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); | 816 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
| 779 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, | 817 int rv = setsockopt(socket_, |
| 780 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); | 818 IPPROTO_IP, |
| 819 IP_DROP_MEMBERSHIP, |
| 820 reinterpret_cast<const char*>(&mreq), |
| 821 sizeof(mreq)); |
| 781 if (rv) | 822 if (rv) |
| 782 return MapSystemError(WSAGetLastError()); | 823 return MapSystemError(WSAGetLastError()); |
| 783 return OK; | 824 return OK; |
| 784 } | 825 } |
| 785 case kIPv6AddressSize: { | 826 case kIPv6AddressSize: { |
| 786 if (addr_family_ != AF_INET6) | 827 if (addr_family_ != AF_INET6) |
| 787 return ERR_ADDRESS_INVALID; | 828 return ERR_ADDRESS_INVALID; |
| 788 ipv6_mreq mreq; | 829 ipv6_mreq mreq; |
| 789 mreq.ipv6mr_interface = multicast_interface_; | 830 mreq.ipv6mr_interface = multicast_interface_; |
| 790 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); | 831 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
| 791 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, | 832 int rv = setsockopt(socket_, |
| 792 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); | 833 IPPROTO_IPV6, |
| 834 IP_DROP_MEMBERSHIP, |
| 835 reinterpret_cast<const char*>(&mreq), |
| 836 sizeof(mreq)); |
| 793 if (rv) | 837 if (rv) |
| 794 return MapSystemError(WSAGetLastError()); | 838 return MapSystemError(WSAGetLastError()); |
| 795 return OK; | 839 return OK; |
| 796 } | 840 } |
| 797 default: | 841 default: |
| 798 NOTREACHED() << "Invalid address family"; | 842 NOTREACHED() << "Invalid address family"; |
| 799 return ERR_ADDRESS_INVALID; | 843 return ERR_ADDRESS_INVALID; |
| 800 } | 844 } |
| 801 } | 845 } |
| 802 | 846 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 // Note: setsockopt(IP_TOS) does not work on windows XP and later. | 879 // Note: setsockopt(IP_TOS) does not work on windows XP and later. |
| 836 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) { | 880 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) { |
| 837 return ERR_NOT_IMPLEMENTED; | 881 return ERR_NOT_IMPLEMENTED; |
| 838 } | 882 } |
| 839 | 883 |
| 840 void UDPSocketWin::DetachFromThread() { | 884 void UDPSocketWin::DetachFromThread() { |
| 841 base::NonThreadSafe::DetachFromThread(); | 885 base::NonThreadSafe::DetachFromThread(); |
| 842 } | 886 } |
| 843 | 887 |
| 844 } // namespace net | 888 } // namespace net |
| OLD | NEW |