| 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/socket/udp_socket_win.h" | 5 #include "net/socket/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/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 qos_handle_(NULL), | 263 qos_handle_(NULL), |
| 264 qos_flow_id_(0) { | 264 qos_flow_id_(0) { |
| 265 EnsureWinsockInit(); | 265 EnsureWinsockInit(); |
| 266 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, | 266 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, |
| 267 source.ToEventParametersCallback()); | 267 source.ToEventParametersCallback()); |
| 268 if (bind_type == DatagramSocket::RANDOM_BIND) | 268 if (bind_type == DatagramSocket::RANDOM_BIND) |
| 269 DCHECK(!rand_int_cb.is_null()); | 269 DCHECK(!rand_int_cb.is_null()); |
| 270 } | 270 } |
| 271 | 271 |
| 272 UDPSocketWin::~UDPSocketWin() { | 272 UDPSocketWin::~UDPSocketWin() { |
| 273 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 273 Close(); | 274 Close(); |
| 274 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); | 275 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); |
| 275 } | 276 } |
| 276 | 277 |
| 277 int UDPSocketWin::Open(AddressFamily address_family) { | 278 int UDPSocketWin::Open(AddressFamily address_family) { |
| 278 DCHECK(CalledOnValidThread()); | 279 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 279 DCHECK_EQ(socket_, INVALID_SOCKET); | 280 DCHECK_EQ(socket_, INVALID_SOCKET); |
| 280 | 281 |
| 281 addr_family_ = ConvertAddressFamily(address_family); | 282 addr_family_ = ConvertAddressFamily(address_family); |
| 282 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); | 283 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); |
| 283 if (socket_ == INVALID_SOCKET) | 284 if (socket_ == INVALID_SOCKET) |
| 284 return MapSystemError(WSAGetLastError()); | 285 return MapSystemError(WSAGetLastError()); |
| 285 if (!use_non_blocking_io_) { | 286 if (!use_non_blocking_io_) { |
| 286 core_ = new Core(this); | 287 core_ = new Core(this); |
| 287 } else { | 288 } else { |
| 288 read_write_event_.Set(WSACreateEvent()); | 289 read_write_event_.Set(WSACreateEvent()); |
| 289 WSAEventSelect(socket_, read_write_event_.Get(), FD_READ | FD_WRITE); | 290 WSAEventSelect(socket_, read_write_event_.Get(), FD_READ | FD_WRITE); |
| 290 } | 291 } |
| 291 return OK; | 292 return OK; |
| 292 } | 293 } |
| 293 | 294 |
| 294 void UDPSocketWin::Close() { | 295 void UDPSocketWin::Close() { |
| 295 DCHECK(CalledOnValidThread()); | 296 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 296 | 297 |
| 297 if (socket_ == INVALID_SOCKET) | 298 if (socket_ == INVALID_SOCKET) |
| 298 return; | 299 return; |
| 299 | 300 |
| 300 if (qos_handle_) { | 301 if (qos_handle_) { |
| 301 QwaveAPI::Get().CloseHandle(qos_handle_); | 302 QwaveAPI::Get().CloseHandle(qos_handle_); |
| 302 } | 303 } |
| 303 | 304 |
| 304 // Zero out any pending read/write callback state. | 305 // Zero out any pending read/write callback state. |
| 305 read_callback_.Reset(); | 306 read_callback_.Reset(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 317 read_write_watcher_.StopWatching(); | 318 read_write_watcher_.StopWatching(); |
| 318 read_write_event_.Close(); | 319 read_write_event_.Close(); |
| 319 | 320 |
| 320 if (core_) { | 321 if (core_) { |
| 321 core_->Detach(); | 322 core_->Detach(); |
| 322 core_ = NULL; | 323 core_ = NULL; |
| 323 } | 324 } |
| 324 } | 325 } |
| 325 | 326 |
| 326 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { | 327 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { |
| 327 DCHECK(CalledOnValidThread()); | 328 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 328 DCHECK(address); | 329 DCHECK(address); |
| 329 if (!is_connected()) | 330 if (!is_connected()) |
| 330 return ERR_SOCKET_NOT_CONNECTED; | 331 return ERR_SOCKET_NOT_CONNECTED; |
| 331 | 332 |
| 332 // TODO(szym): Simplify. http://crbug.com/126152 | 333 // TODO(szym): Simplify. http://crbug.com/126152 |
| 333 if (!remote_address_.get()) { | 334 if (!remote_address_.get()) { |
| 334 SockaddrStorage storage; | 335 SockaddrStorage storage; |
| 335 if (getpeername(socket_, storage.addr, &storage.addr_len)) | 336 if (getpeername(socket_, storage.addr, &storage.addr_len)) |
| 336 return MapSystemError(WSAGetLastError()); | 337 return MapSystemError(WSAGetLastError()); |
| 337 std::unique_ptr<IPEndPoint> remote_address(new IPEndPoint()); | 338 std::unique_ptr<IPEndPoint> remote_address(new IPEndPoint()); |
| 338 if (!remote_address->FromSockAddr(storage.addr, storage.addr_len)) | 339 if (!remote_address->FromSockAddr(storage.addr, storage.addr_len)) |
| 339 return ERR_ADDRESS_INVALID; | 340 return ERR_ADDRESS_INVALID; |
| 340 remote_address_ = std::move(remote_address); | 341 remote_address_ = std::move(remote_address); |
| 341 } | 342 } |
| 342 | 343 |
| 343 *address = *remote_address_; | 344 *address = *remote_address_; |
| 344 return OK; | 345 return OK; |
| 345 } | 346 } |
| 346 | 347 |
| 347 int UDPSocketWin::GetLocalAddress(IPEndPoint* address) const { | 348 int UDPSocketWin::GetLocalAddress(IPEndPoint* address) const { |
| 348 DCHECK(CalledOnValidThread()); | 349 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 349 DCHECK(address); | 350 DCHECK(address); |
| 350 if (!is_connected()) | 351 if (!is_connected()) |
| 351 return ERR_SOCKET_NOT_CONNECTED; | 352 return ERR_SOCKET_NOT_CONNECTED; |
| 352 | 353 |
| 353 // TODO(szym): Simplify. http://crbug.com/126152 | 354 // TODO(szym): Simplify. http://crbug.com/126152 |
| 354 if (!local_address_.get()) { | 355 if (!local_address_.get()) { |
| 355 SockaddrStorage storage; | 356 SockaddrStorage storage; |
| 356 if (getsockname(socket_, storage.addr, &storage.addr_len)) | 357 if (getsockname(socket_, storage.addr, &storage.addr_len)) |
| 357 return MapSystemError(WSAGetLastError()); | 358 return MapSystemError(WSAGetLastError()); |
| 358 std::unique_ptr<IPEndPoint> local_address(new IPEndPoint()); | 359 std::unique_ptr<IPEndPoint> local_address(new IPEndPoint()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 372 int UDPSocketWin::Read(IOBuffer* buf, | 373 int UDPSocketWin::Read(IOBuffer* buf, |
| 373 int buf_len, | 374 int buf_len, |
| 374 const CompletionCallback& callback) { | 375 const CompletionCallback& callback) { |
| 375 return RecvFrom(buf, buf_len, NULL, callback); | 376 return RecvFrom(buf, buf_len, NULL, callback); |
| 376 } | 377 } |
| 377 | 378 |
| 378 int UDPSocketWin::RecvFrom(IOBuffer* buf, | 379 int UDPSocketWin::RecvFrom(IOBuffer* buf, |
| 379 int buf_len, | 380 int buf_len, |
| 380 IPEndPoint* address, | 381 IPEndPoint* address, |
| 381 const CompletionCallback& callback) { | 382 const CompletionCallback& callback) { |
| 382 DCHECK(CalledOnValidThread()); | 383 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 383 DCHECK_NE(INVALID_SOCKET, socket_); | 384 DCHECK_NE(INVALID_SOCKET, socket_); |
| 384 CHECK(read_callback_.is_null()); | 385 CHECK(read_callback_.is_null()); |
| 385 DCHECK(!recv_from_address_); | 386 DCHECK(!recv_from_address_); |
| 386 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 387 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
| 387 DCHECK_GT(buf_len, 0); | 388 DCHECK_GT(buf_len, 0); |
| 388 | 389 |
| 389 int nread = core_ ? InternalRecvFromOverlapped(buf, buf_len, address) | 390 int nread = core_ ? InternalRecvFromOverlapped(buf, buf_len, address) |
| 390 : InternalRecvFromNonBlocking(buf, buf_len, address); | 391 : InternalRecvFromNonBlocking(buf, buf_len, address); |
| 391 if (nread != ERR_IO_PENDING) | 392 if (nread != ERR_IO_PENDING) |
| 392 return nread; | 393 return nread; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 406 int buf_len, | 407 int buf_len, |
| 407 const IPEndPoint& address, | 408 const IPEndPoint& address, |
| 408 const CompletionCallback& callback) { | 409 const CompletionCallback& callback) { |
| 409 return SendToOrWrite(buf, buf_len, &address, callback); | 410 return SendToOrWrite(buf, buf_len, &address, callback); |
| 410 } | 411 } |
| 411 | 412 |
| 412 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, | 413 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, |
| 413 int buf_len, | 414 int buf_len, |
| 414 const IPEndPoint* address, | 415 const IPEndPoint* address, |
| 415 const CompletionCallback& callback) { | 416 const CompletionCallback& callback) { |
| 416 DCHECK(CalledOnValidThread()); | 417 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 417 DCHECK_NE(INVALID_SOCKET, socket_); | 418 DCHECK_NE(INVALID_SOCKET, socket_); |
| 418 CHECK(write_callback_.is_null()); | 419 CHECK(write_callback_.is_null()); |
| 419 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 420 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
| 420 DCHECK_GT(buf_len, 0); | 421 DCHECK_GT(buf_len, 0); |
| 421 DCHECK(!send_to_address_.get()); | 422 DCHECK(!send_to_address_.get()); |
| 422 | 423 |
| 423 int nwrite = core_ ? InternalSendToOverlapped(buf, buf_len, address) | 424 int nwrite = core_ ? InternalSendToOverlapped(buf, buf_len, address) |
| 424 : InternalSendToNonBlocking(buf, buf_len, address); | 425 : InternalSendToNonBlocking(buf, buf_len, address); |
| 425 if (nwrite != ERR_IO_PENDING) | 426 if (nwrite != ERR_IO_PENDING) |
| 426 return nwrite; | 427 return nwrite; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 return rv; | 493 return rv; |
| 493 } | 494 } |
| 494 | 495 |
| 495 int UDPSocketWin::BindToNetwork(NetworkChangeNotifier::NetworkHandle network) { | 496 int UDPSocketWin::BindToNetwork(NetworkChangeNotifier::NetworkHandle network) { |
| 496 NOTIMPLEMENTED(); | 497 NOTIMPLEMENTED(); |
| 497 return ERR_NOT_IMPLEMENTED; | 498 return ERR_NOT_IMPLEMENTED; |
| 498 } | 499 } |
| 499 | 500 |
| 500 int UDPSocketWin::SetReceiveBufferSize(int32_t size) { | 501 int UDPSocketWin::SetReceiveBufferSize(int32_t size) { |
| 501 DCHECK_NE(socket_, INVALID_SOCKET); | 502 DCHECK_NE(socket_, INVALID_SOCKET); |
| 502 DCHECK(CalledOnValidThread()); | 503 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 503 int rv = SetSocketReceiveBufferSize(socket_, size); | 504 int rv = SetSocketReceiveBufferSize(socket_, size); |
| 504 | 505 |
| 505 if (rv != 0) | 506 if (rv != 0) |
| 506 return MapSystemError(WSAGetLastError()); | 507 return MapSystemError(WSAGetLastError()); |
| 507 | 508 |
| 508 // According to documentation, setsockopt may succeed, but we need to check | 509 // According to documentation, setsockopt may succeed, but we need to check |
| 509 // the results via getsockopt to be sure it works on Windows. | 510 // the results via getsockopt to be sure it works on Windows. |
| 510 int32_t actual_size = 0; | 511 int32_t actual_size = 0; |
| 511 int option_size = sizeof(actual_size); | 512 int option_size = sizeof(actual_size); |
| 512 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF, | 513 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF, |
| 513 reinterpret_cast<char*>(&actual_size), &option_size); | 514 reinterpret_cast<char*>(&actual_size), &option_size); |
| 514 if (rv != 0) | 515 if (rv != 0) |
| 515 return MapSystemError(WSAGetLastError()); | 516 return MapSystemError(WSAGetLastError()); |
| 516 if (actual_size >= size) | 517 if (actual_size >= size) |
| 517 return OK; | 518 return OK; |
| 518 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer", | 519 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer", |
| 519 actual_size, 1000, 1000000, 50); | 520 actual_size, 1000, 1000000, 50); |
| 520 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE; | 521 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE; |
| 521 } | 522 } |
| 522 | 523 |
| 523 int UDPSocketWin::SetSendBufferSize(int32_t size) { | 524 int UDPSocketWin::SetSendBufferSize(int32_t size) { |
| 524 DCHECK_NE(socket_, INVALID_SOCKET); | 525 DCHECK_NE(socket_, INVALID_SOCKET); |
| 525 DCHECK(CalledOnValidThread()); | 526 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 526 int rv = SetSocketSendBufferSize(socket_, size); | 527 int rv = SetSocketSendBufferSize(socket_, size); |
| 527 if (rv != 0) | 528 if (rv != 0) |
| 528 return MapSystemError(WSAGetLastError()); | 529 return MapSystemError(WSAGetLastError()); |
| 529 // According to documentation, setsockopt may succeed, but we need to check | 530 // According to documentation, setsockopt may succeed, but we need to check |
| 530 // the results via getsockopt to be sure it works on Windows. | 531 // the results via getsockopt to be sure it works on Windows. |
| 531 int32_t actual_size = 0; | 532 int32_t actual_size = 0; |
| 532 int option_size = sizeof(actual_size); | 533 int option_size = sizeof(actual_size); |
| 533 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 534 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
| 534 reinterpret_cast<char*>(&actual_size), &option_size); | 535 reinterpret_cast<char*>(&actual_size), &option_size); |
| 535 if (rv != 0) | 536 if (rv != 0) |
| 536 return MapSystemError(WSAGetLastError()); | 537 return MapSystemError(WSAGetLastError()); |
| 537 if (actual_size >= size) | 538 if (actual_size >= size) |
| 538 return OK; | 539 return OK; |
| 539 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer", | 540 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer", |
| 540 actual_size, 1000, 1000000, 50); | 541 actual_size, 1000, 1000000, 50); |
| 541 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE; | 542 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE; |
| 542 } | 543 } |
| 543 | 544 |
| 544 int UDPSocketWin::SetDoNotFragment() { | 545 int UDPSocketWin::SetDoNotFragment() { |
| 545 DCHECK_NE(socket_, INVALID_SOCKET); | 546 DCHECK_NE(socket_, INVALID_SOCKET); |
| 546 DCHECK(CalledOnValidThread()); | 547 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 547 | 548 |
| 548 if (addr_family_ == AF_INET6) | 549 if (addr_family_ == AF_INET6) |
| 549 return OK; | 550 return OK; |
| 550 | 551 |
| 551 DWORD val = 1; | 552 DWORD val = 1; |
| 552 int rv = setsockopt(socket_, IPPROTO_IP, IP_DONTFRAGMENT, | 553 int rv = setsockopt(socket_, IPPROTO_IP, IP_DONTFRAGMENT, |
| 553 reinterpret_cast<const char*>(&val), sizeof(val)); | 554 reinterpret_cast<const char*>(&val), sizeof(val)); |
| 554 return rv == 0 ? OK : MapSystemError(WSAGetLastError()); | 555 return rv == 0 ? OK : MapSystemError(WSAGetLastError()); |
| 555 } | 556 } |
| 556 | 557 |
| 557 int UDPSocketWin::AllowAddressReuse() { | 558 int UDPSocketWin::AllowAddressReuse() { |
| 558 DCHECK_NE(socket_, INVALID_SOCKET); | 559 DCHECK_NE(socket_, INVALID_SOCKET); |
| 559 DCHECK(CalledOnValidThread()); | 560 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 560 DCHECK(!is_connected()); | 561 DCHECK(!is_connected()); |
| 561 | 562 |
| 562 BOOL true_value = TRUE; | 563 BOOL true_value = TRUE; |
| 563 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, | 564 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, |
| 564 reinterpret_cast<const char*>(&true_value), | 565 reinterpret_cast<const char*>(&true_value), |
| 565 sizeof(true_value)); | 566 sizeof(true_value)); |
| 566 return rv == 0 ? OK : MapSystemError(WSAGetLastError()); | 567 return rv == 0 ? OK : MapSystemError(WSAGetLastError()); |
| 567 } | 568 } |
| 568 | 569 |
| 569 int UDPSocketWin::SetBroadcast(bool broadcast) { | 570 int UDPSocketWin::SetBroadcast(bool broadcast) { |
| 570 DCHECK_NE(socket_, INVALID_SOCKET); | 571 DCHECK_NE(socket_, INVALID_SOCKET); |
| 571 DCHECK(CalledOnValidThread()); | 572 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 572 | 573 |
| 573 BOOL value = broadcast ? TRUE : FALSE; | 574 BOOL value = broadcast ? TRUE : FALSE; |
| 574 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, | 575 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, |
| 575 reinterpret_cast<const char*>(&value), sizeof(value)); | 576 reinterpret_cast<const char*>(&value), sizeof(value)); |
| 576 return rv == 0 ? OK : MapSystemError(WSAGetLastError()); | 577 return rv == 0 ? OK : MapSystemError(WSAGetLastError()); |
| 577 } | 578 } |
| 578 | 579 |
| 579 void UDPSocketWin::DoReadCallback(int rv) { | 580 void UDPSocketWin::DoReadCallback(int rv) { |
| 580 DCHECK_NE(rv, ERR_IO_PENDING); | 581 DCHECK_NE(rv, ERR_IO_PENDING); |
| 581 DCHECK(!read_callback_.is_null()); | 582 DCHECK(!read_callback_.is_null()); |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 981 for (int i = 0; i < kBindRetries; ++i) { | 982 for (int i = 0; i < kBindRetries; ++i) { |
| 982 int rv = DoBind(IPEndPoint(address, static_cast<uint16_t>(rand_int_cb_.Run( | 983 int rv = DoBind(IPEndPoint(address, static_cast<uint16_t>(rand_int_cb_.Run( |
| 983 kPortStart, kPortEnd)))); | 984 kPortStart, kPortEnd)))); |
| 984 if (rv != ERR_ADDRESS_IN_USE) | 985 if (rv != ERR_ADDRESS_IN_USE) |
| 985 return rv; | 986 return rv; |
| 986 } | 987 } |
| 987 return DoBind(IPEndPoint(address, 0)); | 988 return DoBind(IPEndPoint(address, 0)); |
| 988 } | 989 } |
| 989 | 990 |
| 990 int UDPSocketWin::JoinGroup(const IPAddress& group_address) const { | 991 int UDPSocketWin::JoinGroup(const IPAddress& group_address) const { |
| 991 DCHECK(CalledOnValidThread()); | 992 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 992 if (!is_connected()) | 993 if (!is_connected()) |
| 993 return ERR_SOCKET_NOT_CONNECTED; | 994 return ERR_SOCKET_NOT_CONNECTED; |
| 994 | 995 |
| 995 switch (group_address.size()) { | 996 switch (group_address.size()) { |
| 996 case IPAddress::kIPv4AddressSize: { | 997 case IPAddress::kIPv4AddressSize: { |
| 997 if (addr_family_ != AF_INET) | 998 if (addr_family_ != AF_INET) |
| 998 return ERR_ADDRESS_INVALID; | 999 return ERR_ADDRESS_INVALID; |
| 999 ip_mreq mreq; | 1000 ip_mreq mreq; |
| 1000 mreq.imr_interface.s_addr = htonl(multicast_interface_); | 1001 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
| 1001 memcpy(&mreq.imr_multiaddr, group_address.bytes().data(), | 1002 memcpy(&mreq.imr_multiaddr, group_address.bytes().data(), |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1021 return MapSystemError(WSAGetLastError()); | 1022 return MapSystemError(WSAGetLastError()); |
| 1022 return OK; | 1023 return OK; |
| 1023 } | 1024 } |
| 1024 default: | 1025 default: |
| 1025 NOTREACHED() << "Invalid address family"; | 1026 NOTREACHED() << "Invalid address family"; |
| 1026 return ERR_ADDRESS_INVALID; | 1027 return ERR_ADDRESS_INVALID; |
| 1027 } | 1028 } |
| 1028 } | 1029 } |
| 1029 | 1030 |
| 1030 int UDPSocketWin::LeaveGroup(const IPAddress& group_address) const { | 1031 int UDPSocketWin::LeaveGroup(const IPAddress& group_address) const { |
| 1031 DCHECK(CalledOnValidThread()); | 1032 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 1032 if (!is_connected()) | 1033 if (!is_connected()) |
| 1033 return ERR_SOCKET_NOT_CONNECTED; | 1034 return ERR_SOCKET_NOT_CONNECTED; |
| 1034 | 1035 |
| 1035 switch (group_address.size()) { | 1036 switch (group_address.size()) { |
| 1036 case IPAddress::kIPv4AddressSize: { | 1037 case IPAddress::kIPv4AddressSize: { |
| 1037 if (addr_family_ != AF_INET) | 1038 if (addr_family_ != AF_INET) |
| 1038 return ERR_ADDRESS_INVALID; | 1039 return ERR_ADDRESS_INVALID; |
| 1039 ip_mreq mreq; | 1040 ip_mreq mreq; |
| 1040 mreq.imr_interface.s_addr = htonl(multicast_interface_); | 1041 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
| 1041 memcpy(&mreq.imr_multiaddr, group_address.bytes().data(), | 1042 memcpy(&mreq.imr_multiaddr, group_address.bytes().data(), |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1059 return MapSystemError(WSAGetLastError()); | 1060 return MapSystemError(WSAGetLastError()); |
| 1060 return OK; | 1061 return OK; |
| 1061 } | 1062 } |
| 1062 default: | 1063 default: |
| 1063 NOTREACHED() << "Invalid address family"; | 1064 NOTREACHED() << "Invalid address family"; |
| 1064 return ERR_ADDRESS_INVALID; | 1065 return ERR_ADDRESS_INVALID; |
| 1065 } | 1066 } |
| 1066 } | 1067 } |
| 1067 | 1068 |
| 1068 int UDPSocketWin::SetMulticastInterface(uint32_t interface_index) { | 1069 int UDPSocketWin::SetMulticastInterface(uint32_t interface_index) { |
| 1069 DCHECK(CalledOnValidThread()); | 1070 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 1070 if (is_connected()) | 1071 if (is_connected()) |
| 1071 return ERR_SOCKET_IS_CONNECTED; | 1072 return ERR_SOCKET_IS_CONNECTED; |
| 1072 multicast_interface_ = interface_index; | 1073 multicast_interface_ = interface_index; |
| 1073 return OK; | 1074 return OK; |
| 1074 } | 1075 } |
| 1075 | 1076 |
| 1076 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) { | 1077 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) { |
| 1077 DCHECK(CalledOnValidThread()); | 1078 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 1078 if (is_connected()) | 1079 if (is_connected()) |
| 1079 return ERR_SOCKET_IS_CONNECTED; | 1080 return ERR_SOCKET_IS_CONNECTED; |
| 1080 | 1081 |
| 1081 if (time_to_live < 0 || time_to_live > 255) | 1082 if (time_to_live < 0 || time_to_live > 255) |
| 1082 return ERR_INVALID_ARGUMENT; | 1083 return ERR_INVALID_ARGUMENT; |
| 1083 multicast_time_to_live_ = time_to_live; | 1084 multicast_time_to_live_ = time_to_live; |
| 1084 return OK; | 1085 return OK; |
| 1085 } | 1086 } |
| 1086 | 1087 |
| 1087 int UDPSocketWin::SetMulticastLoopbackMode(bool loopback) { | 1088 int UDPSocketWin::SetMulticastLoopbackMode(bool loopback) { |
| 1088 DCHECK(CalledOnValidThread()); | 1089 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 1089 if (is_connected()) | 1090 if (is_connected()) |
| 1090 return ERR_SOCKET_IS_CONNECTED; | 1091 return ERR_SOCKET_IS_CONNECTED; |
| 1091 | 1092 |
| 1092 if (loopback) | 1093 if (loopback) |
| 1093 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP; | 1094 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP; |
| 1094 else | 1095 else |
| 1095 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP; | 1096 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP; |
| 1096 return OK; | 1097 return OK; |
| 1097 } | 1098 } |
| 1098 | 1099 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 QOSSetOutgoingDSCPValue, | 1184 QOSSetOutgoingDSCPValue, |
| 1184 sizeof(buf), | 1185 sizeof(buf), |
| 1185 &buf, | 1186 &buf, |
| 1186 0, | 1187 0, |
| 1187 NULL); | 1188 NULL); |
| 1188 | 1189 |
| 1189 return OK; | 1190 return OK; |
| 1190 } | 1191 } |
| 1191 | 1192 |
| 1192 void UDPSocketWin::DetachFromThread() { | 1193 void UDPSocketWin::DetachFromThread() { |
| 1193 base::NonThreadSafe::DetachFromThread(); | 1194 DETACH_FROM_THREAD(thread_checker_); |
| 1194 } | 1195 } |
| 1195 | 1196 |
| 1196 void UDPSocketWin::UseNonBlockingIO() { | 1197 void UDPSocketWin::UseNonBlockingIO() { |
| 1197 DCHECK(!core_); | 1198 DCHECK(!core_); |
| 1198 use_non_blocking_io_ = true; | 1199 use_non_blocking_io_ = true; |
| 1199 } | 1200 } |
| 1200 | 1201 |
| 1201 } // namespace net | 1202 } // namespace net |
| OLD | NEW |