| 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_posix.h" | 5 #include "net/socket/udp_socket_posix.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <net/if.h> | 9 #include <net/if.h> |
| 10 #include <netdb.h> | 10 #include <netdb.h> |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 write_buf_len_(0), | 172 write_buf_len_(0), |
| 173 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::UDP_SOCKET)), | 173 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::UDP_SOCKET)), |
| 174 bound_network_(NetworkChangeNotifier::kInvalidNetworkHandle) { | 174 bound_network_(NetworkChangeNotifier::kInvalidNetworkHandle) { |
| 175 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, | 175 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, |
| 176 source.ToEventParametersCallback()); | 176 source.ToEventParametersCallback()); |
| 177 if (bind_type == DatagramSocket::RANDOM_BIND) | 177 if (bind_type == DatagramSocket::RANDOM_BIND) |
| 178 DCHECK(!rand_int_cb.is_null()); | 178 DCHECK(!rand_int_cb.is_null()); |
| 179 } | 179 } |
| 180 | 180 |
| 181 UDPSocketPosix::~UDPSocketPosix() { | 181 UDPSocketPosix::~UDPSocketPosix() { |
| 182 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 182 Close(); | 183 Close(); |
| 183 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); | 184 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); |
| 184 } | 185 } |
| 185 | 186 |
| 186 int UDPSocketPosix::Open(AddressFamily address_family) { | 187 int UDPSocketPosix::Open(AddressFamily address_family) { |
| 187 DCHECK(CalledOnValidThread()); | 188 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 188 DCHECK_EQ(socket_, kInvalidSocket); | 189 DCHECK_EQ(socket_, kInvalidSocket); |
| 189 | 190 |
| 190 addr_family_ = ConvertAddressFamily(address_family); | 191 addr_family_ = ConvertAddressFamily(address_family); |
| 191 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0); | 192 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0); |
| 192 if (socket_ == kInvalidSocket) | 193 if (socket_ == kInvalidSocket) |
| 193 return MapSystemError(errno); | 194 return MapSystemError(errno); |
| 194 #if defined(OS_MACOSX) && !defined(OS_IOS) | 195 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 195 PCHECK(change_fdguard_np(socket_, NULL, 0, &kSocketFdGuard, | 196 PCHECK(change_fdguard_np(socket_, NULL, 0, &kSocketFdGuard, |
| 196 GUARD_CLOSE | GUARD_DUP, NULL) == 0); | 197 GUARD_CLOSE | GUARD_DUP, NULL) == 0); |
| 197 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 198 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 198 if (!base::SetNonBlocking(socket_)) { | 199 if (!base::SetNonBlocking(socket_)) { |
| 199 const int err = MapSystemError(errno); | 200 const int err = MapSystemError(errno); |
| 200 Close(); | 201 Close(); |
| 201 return err; | 202 return err; |
| 202 } | 203 } |
| 203 return OK; | 204 return OK; |
| 204 } | 205 } |
| 205 | 206 |
| 206 void UDPSocketPosix::Close() { | 207 void UDPSocketPosix::Close() { |
| 207 DCHECK(CalledOnValidThread()); | 208 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 208 | 209 |
| 209 if (socket_ == kInvalidSocket) | 210 if (socket_ == kInvalidSocket) |
| 210 return; | 211 return; |
| 211 | 212 |
| 212 // Zero out any pending read/write callback state. | 213 // Zero out any pending read/write callback state. |
| 213 read_buf_ = NULL; | 214 read_buf_ = NULL; |
| 214 read_buf_len_ = 0; | 215 read_buf_len_ = 0; |
| 215 read_callback_.Reset(); | 216 read_callback_.Reset(); |
| 216 recv_from_address_ = NULL; | 217 recv_from_address_ = NULL; |
| 217 write_buf_ = NULL; | 218 write_buf_ = NULL; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 229 #else | 230 #else |
| 230 PCHECK(IGNORE_EINTR(close(socket_)) == 0); | 231 PCHECK(IGNORE_EINTR(close(socket_)) == 0); |
| 231 #endif // defined(OS_MACOSX) && !defined(OS_IOS) | 232 #endif // defined(OS_MACOSX) && !defined(OS_IOS) |
| 232 | 233 |
| 233 socket_ = kInvalidSocket; | 234 socket_ = kInvalidSocket; |
| 234 addr_family_ = 0; | 235 addr_family_ = 0; |
| 235 is_connected_ = false; | 236 is_connected_ = false; |
| 236 } | 237 } |
| 237 | 238 |
| 238 int UDPSocketPosix::GetPeerAddress(IPEndPoint* address) const { | 239 int UDPSocketPosix::GetPeerAddress(IPEndPoint* address) const { |
| 239 DCHECK(CalledOnValidThread()); | 240 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 240 DCHECK(address); | 241 DCHECK(address); |
| 241 if (!is_connected()) | 242 if (!is_connected()) |
| 242 return ERR_SOCKET_NOT_CONNECTED; | 243 return ERR_SOCKET_NOT_CONNECTED; |
| 243 | 244 |
| 244 if (!remote_address_.get()) { | 245 if (!remote_address_.get()) { |
| 245 SockaddrStorage storage; | 246 SockaddrStorage storage; |
| 246 if (getpeername(socket_, storage.addr, &storage.addr_len)) | 247 if (getpeername(socket_, storage.addr, &storage.addr_len)) |
| 247 return MapSystemError(errno); | 248 return MapSystemError(errno); |
| 248 std::unique_ptr<IPEndPoint> address(new IPEndPoint()); | 249 std::unique_ptr<IPEndPoint> address(new IPEndPoint()); |
| 249 if (!address->FromSockAddr(storage.addr, storage.addr_len)) | 250 if (!address->FromSockAddr(storage.addr, storage.addr_len)) |
| 250 return ERR_ADDRESS_INVALID; | 251 return ERR_ADDRESS_INVALID; |
| 251 remote_address_ = std::move(address); | 252 remote_address_ = std::move(address); |
| 252 } | 253 } |
| 253 | 254 |
| 254 *address = *remote_address_; | 255 *address = *remote_address_; |
| 255 return OK; | 256 return OK; |
| 256 } | 257 } |
| 257 | 258 |
| 258 int UDPSocketPosix::GetLocalAddress(IPEndPoint* address) const { | 259 int UDPSocketPosix::GetLocalAddress(IPEndPoint* address) const { |
| 259 DCHECK(CalledOnValidThread()); | 260 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 260 DCHECK(address); | 261 DCHECK(address); |
| 261 if (!is_connected()) | 262 if (!is_connected()) |
| 262 return ERR_SOCKET_NOT_CONNECTED; | 263 return ERR_SOCKET_NOT_CONNECTED; |
| 263 | 264 |
| 264 if (!local_address_.get()) { | 265 if (!local_address_.get()) { |
| 265 SockaddrStorage storage; | 266 SockaddrStorage storage; |
| 266 if (getsockname(socket_, storage.addr, &storage.addr_len)) | 267 if (getsockname(socket_, storage.addr, &storage.addr_len)) |
| 267 return MapSystemError(errno); | 268 return MapSystemError(errno); |
| 268 std::unique_ptr<IPEndPoint> address(new IPEndPoint()); | 269 std::unique_ptr<IPEndPoint> address(new IPEndPoint()); |
| 269 if (!address->FromSockAddr(storage.addr, storage.addr_len)) | 270 if (!address->FromSockAddr(storage.addr, storage.addr_len)) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 281 int UDPSocketPosix::Read(IOBuffer* buf, | 282 int UDPSocketPosix::Read(IOBuffer* buf, |
| 282 int buf_len, | 283 int buf_len, |
| 283 const CompletionCallback& callback) { | 284 const CompletionCallback& callback) { |
| 284 return RecvFrom(buf, buf_len, NULL, callback); | 285 return RecvFrom(buf, buf_len, NULL, callback); |
| 285 } | 286 } |
| 286 | 287 |
| 287 int UDPSocketPosix::RecvFrom(IOBuffer* buf, | 288 int UDPSocketPosix::RecvFrom(IOBuffer* buf, |
| 288 int buf_len, | 289 int buf_len, |
| 289 IPEndPoint* address, | 290 IPEndPoint* address, |
| 290 const CompletionCallback& callback) { | 291 const CompletionCallback& callback) { |
| 291 DCHECK(CalledOnValidThread()); | 292 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 292 DCHECK_NE(kInvalidSocket, socket_); | 293 DCHECK_NE(kInvalidSocket, socket_); |
| 293 CHECK(read_callback_.is_null()); | 294 CHECK(read_callback_.is_null()); |
| 294 DCHECK(!recv_from_address_); | 295 DCHECK(!recv_from_address_); |
| 295 DCHECK(!callback.is_null()); // Synchronous operation not supported | 296 DCHECK(!callback.is_null()); // Synchronous operation not supported |
| 296 DCHECK_GT(buf_len, 0); | 297 DCHECK_GT(buf_len, 0); |
| 297 | 298 |
| 298 int nread = InternalRecvFrom(buf, buf_len, address); | 299 int nread = InternalRecvFrom(buf, buf_len, address); |
| 299 if (nread != ERR_IO_PENDING) | 300 if (nread != ERR_IO_PENDING) |
| 300 return nread; | 301 return nread; |
| 301 | 302 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 325 int buf_len, | 326 int buf_len, |
| 326 const IPEndPoint& address, | 327 const IPEndPoint& address, |
| 327 const CompletionCallback& callback) { | 328 const CompletionCallback& callback) { |
| 328 return SendToOrWrite(buf, buf_len, &address, callback); | 329 return SendToOrWrite(buf, buf_len, &address, callback); |
| 329 } | 330 } |
| 330 | 331 |
| 331 int UDPSocketPosix::SendToOrWrite(IOBuffer* buf, | 332 int UDPSocketPosix::SendToOrWrite(IOBuffer* buf, |
| 332 int buf_len, | 333 int buf_len, |
| 333 const IPEndPoint* address, | 334 const IPEndPoint* address, |
| 334 const CompletionCallback& callback) { | 335 const CompletionCallback& callback) { |
| 335 DCHECK(CalledOnValidThread()); | 336 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 336 DCHECK_NE(kInvalidSocket, socket_); | 337 DCHECK_NE(kInvalidSocket, socket_); |
| 337 CHECK(write_callback_.is_null()); | 338 CHECK(write_callback_.is_null()); |
| 338 DCHECK(!callback.is_null()); // Synchronous operation not supported | 339 DCHECK(!callback.is_null()); // Synchronous operation not supported |
| 339 DCHECK_GT(buf_len, 0); | 340 DCHECK_GT(buf_len, 0); |
| 340 | 341 |
| 341 int result = InternalSendTo(buf, buf_len, address); | 342 int result = InternalSendTo(buf, buf_len, address); |
| 342 if (result != ERR_IO_PENDING) | 343 if (result != ERR_IO_PENDING) |
| 343 return result; | 344 return result; |
| 344 | 345 |
| 345 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( | 346 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( |
| (...skipping 19 matching lines...) Expand all Loading... |
| 365 DCHECK_NE(socket_, kInvalidSocket); | 366 DCHECK_NE(socket_, kInvalidSocket); |
| 366 net_log_.BeginEvent(NetLogEventType::UDP_CONNECT, | 367 net_log_.BeginEvent(NetLogEventType::UDP_CONNECT, |
| 367 CreateNetLogUDPConnectCallback(&address, bound_network_)); | 368 CreateNetLogUDPConnectCallback(&address, bound_network_)); |
| 368 int rv = InternalConnect(address); | 369 int rv = InternalConnect(address); |
| 369 net_log_.EndEventWithNetErrorCode(NetLogEventType::UDP_CONNECT, rv); | 370 net_log_.EndEventWithNetErrorCode(NetLogEventType::UDP_CONNECT, rv); |
| 370 is_connected_ = (rv == OK); | 371 is_connected_ = (rv == OK); |
| 371 return rv; | 372 return rv; |
| 372 } | 373 } |
| 373 | 374 |
| 374 int UDPSocketPosix::InternalConnect(const IPEndPoint& address) { | 375 int UDPSocketPosix::InternalConnect(const IPEndPoint& address) { |
| 375 DCHECK(CalledOnValidThread()); | 376 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 376 DCHECK(!is_connected()); | 377 DCHECK(!is_connected()); |
| 377 DCHECK(!remote_address_.get()); | 378 DCHECK(!remote_address_.get()); |
| 378 | 379 |
| 379 int rv = 0; | 380 int rv = 0; |
| 380 if (bind_type_ == DatagramSocket::RANDOM_BIND) { | 381 if (bind_type_ == DatagramSocket::RANDOM_BIND) { |
| 381 // Construct IPAddress of appropriate size (IPv4 or IPv6) of 0s, | 382 // Construct IPAddress of appropriate size (IPv4 or IPv6) of 0s, |
| 382 // representing INADDR_ANY or in6addr_any. | 383 // representing INADDR_ANY or in6addr_any. |
| 383 size_t addr_size = address.GetSockAddrFamily() == AF_INET | 384 size_t addr_size = address.GetSockAddrFamily() == AF_INET |
| 384 ? IPAddress::kIPv4AddressSize | 385 ? IPAddress::kIPv4AddressSize |
| 385 : IPAddress::kIPv6AddressSize; | 386 : IPAddress::kIPv6AddressSize; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 399 rv = HANDLE_EINTR(connect(socket_, storage.addr, storage.addr_len)); | 400 rv = HANDLE_EINTR(connect(socket_, storage.addr, storage.addr_len)); |
| 400 if (rv < 0) | 401 if (rv < 0) |
| 401 return MapSystemError(errno); | 402 return MapSystemError(errno); |
| 402 | 403 |
| 403 remote_address_.reset(new IPEndPoint(address)); | 404 remote_address_.reset(new IPEndPoint(address)); |
| 404 return rv; | 405 return rv; |
| 405 } | 406 } |
| 406 | 407 |
| 407 int UDPSocketPosix::Bind(const IPEndPoint& address) { | 408 int UDPSocketPosix::Bind(const IPEndPoint& address) { |
| 408 DCHECK_NE(socket_, kInvalidSocket); | 409 DCHECK_NE(socket_, kInvalidSocket); |
| 409 DCHECK(CalledOnValidThread()); | 410 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 410 DCHECK(!is_connected()); | 411 DCHECK(!is_connected()); |
| 411 | 412 |
| 412 int rv = SetMulticastOptions(); | 413 int rv = SetMulticastOptions(); |
| 413 if (rv < 0) | 414 if (rv < 0) |
| 414 return rv; | 415 return rv; |
| 415 | 416 |
| 416 rv = DoBind(address); | 417 rv = DoBind(address); |
| 417 if (rv < 0) | 418 if (rv < 0) |
| 418 return rv; | 419 return rv; |
| 419 | 420 |
| 420 is_connected_ = true; | 421 is_connected_ = true; |
| 421 local_address_.reset(); | 422 local_address_.reset(); |
| 422 return rv; | 423 return rv; |
| 423 } | 424 } |
| 424 | 425 |
| 425 int UDPSocketPosix::BindToNetwork( | 426 int UDPSocketPosix::BindToNetwork( |
| 426 NetworkChangeNotifier::NetworkHandle network) { | 427 NetworkChangeNotifier::NetworkHandle network) { |
| 427 DCHECK_NE(socket_, kInvalidSocket); | 428 DCHECK_NE(socket_, kInvalidSocket); |
| 428 DCHECK(CalledOnValidThread()); | 429 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 429 DCHECK(!is_connected()); | 430 DCHECK(!is_connected()); |
| 430 if (network == NetworkChangeNotifier::kInvalidNetworkHandle) | 431 if (network == NetworkChangeNotifier::kInvalidNetworkHandle) |
| 431 return ERR_INVALID_ARGUMENT; | 432 return ERR_INVALID_ARGUMENT; |
| 432 #if defined(OS_ANDROID) | 433 #if defined(OS_ANDROID) |
| 433 // Android prior to Lollipop didn't have support for binding sockets to | 434 // Android prior to Lollipop didn't have support for binding sockets to |
| 434 // networks. | 435 // networks. |
| 435 if (base::android::BuildInfo::GetInstance()->sdk_int() < | 436 if (base::android::BuildInfo::GetInstance()->sdk_int() < |
| 436 base::android::SDK_VERSION_LOLLIPOP) { | 437 base::android::SDK_VERSION_LOLLIPOP) { |
| 437 return ERR_NOT_IMPLEMENTED; | 438 return ERR_NOT_IMPLEMENTED; |
| 438 } | 439 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 bound_network_ = network; | 495 bound_network_ = network; |
| 495 return MapSystemError(rv); | 496 return MapSystemError(rv); |
| 496 #else | 497 #else |
| 497 NOTIMPLEMENTED(); | 498 NOTIMPLEMENTED(); |
| 498 return ERR_NOT_IMPLEMENTED; | 499 return ERR_NOT_IMPLEMENTED; |
| 499 #endif | 500 #endif |
| 500 } | 501 } |
| 501 | 502 |
| 502 int UDPSocketPosix::SetReceiveBufferSize(int32_t size) { | 503 int UDPSocketPosix::SetReceiveBufferSize(int32_t size) { |
| 503 DCHECK_NE(socket_, kInvalidSocket); | 504 DCHECK_NE(socket_, kInvalidSocket); |
| 504 DCHECK(CalledOnValidThread()); | 505 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 505 return SetSocketReceiveBufferSize(socket_, size); | 506 return SetSocketReceiveBufferSize(socket_, size); |
| 506 } | 507 } |
| 507 | 508 |
| 508 int UDPSocketPosix::SetSendBufferSize(int32_t size) { | 509 int UDPSocketPosix::SetSendBufferSize(int32_t size) { |
| 509 DCHECK_NE(socket_, kInvalidSocket); | 510 DCHECK_NE(socket_, kInvalidSocket); |
| 510 DCHECK(CalledOnValidThread()); | 511 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 511 return SetSocketSendBufferSize(socket_, size); | 512 return SetSocketSendBufferSize(socket_, size); |
| 512 } | 513 } |
| 513 | 514 |
| 514 int UDPSocketPosix::SetDoNotFragment() { | 515 int UDPSocketPosix::SetDoNotFragment() { |
| 515 DCHECK_NE(socket_, kInvalidSocket); | 516 DCHECK_NE(socket_, kInvalidSocket); |
| 516 DCHECK(CalledOnValidThread()); | 517 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 517 | 518 |
| 518 #if !defined(IP_PMTUDISC_DO) | 519 #if !defined(IP_PMTUDISC_DO) |
| 519 return ERR_NOT_IMPLEMENTED; | 520 return ERR_NOT_IMPLEMENTED; |
| 520 #else | 521 #else |
| 521 if (addr_family_ == AF_INET6) { | 522 if (addr_family_ == AF_INET6) { |
| 522 int val = IPV6_PMTUDISC_DO; | 523 int val = IPV6_PMTUDISC_DO; |
| 523 if (setsockopt(socket_, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val, | 524 if (setsockopt(socket_, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val, |
| 524 sizeof(val)) != 0) { | 525 sizeof(val)) != 0) { |
| 525 return MapSystemError(errno); | 526 return MapSystemError(errno); |
| 526 } | 527 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 537 } | 538 } |
| 538 | 539 |
| 539 int val = IP_PMTUDISC_DO; | 540 int val = IP_PMTUDISC_DO; |
| 540 int rv = setsockopt(socket_, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)); | 541 int rv = setsockopt(socket_, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val)); |
| 541 return rv == 0 ? OK : MapSystemError(errno); | 542 return rv == 0 ? OK : MapSystemError(errno); |
| 542 #endif | 543 #endif |
| 543 } | 544 } |
| 544 | 545 |
| 545 int UDPSocketPosix::AllowAddressReuse() { | 546 int UDPSocketPosix::AllowAddressReuse() { |
| 546 DCHECK_NE(socket_, kInvalidSocket); | 547 DCHECK_NE(socket_, kInvalidSocket); |
| 547 DCHECK(CalledOnValidThread()); | 548 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 548 DCHECK(!is_connected()); | 549 DCHECK(!is_connected()); |
| 549 return SetReuseAddr(socket_, true); | 550 return SetReuseAddr(socket_, true); |
| 550 } | 551 } |
| 551 | 552 |
| 552 int UDPSocketPosix::SetBroadcast(bool broadcast) { | 553 int UDPSocketPosix::SetBroadcast(bool broadcast) { |
| 553 DCHECK_NE(socket_, kInvalidSocket); | 554 DCHECK_NE(socket_, kInvalidSocket); |
| 554 DCHECK(CalledOnValidThread()); | 555 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 555 int value = broadcast ? 1 : 0; | 556 int value = broadcast ? 1 : 0; |
| 556 int rv; | 557 int rv; |
| 557 #if defined(OS_MACOSX) | 558 #if defined(OS_MACOSX) |
| 558 // SO_REUSEPORT on OSX permits multiple processes to each receive | 559 // SO_REUSEPORT on OSX permits multiple processes to each receive |
| 559 // UDP multicast or broadcast datagrams destined for the bound | 560 // UDP multicast or broadcast datagrams destined for the bound |
| 560 // port. | 561 // port. |
| 561 // This is only being set on OSX because its behavior is platform dependent | 562 // This is only being set on OSX because its behavior is platform dependent |
| 562 // and we are playing it safe by only setting it on platforms where things | 563 // and we are playing it safe by only setting it on platforms where things |
| 563 // break. | 564 // break. |
| 564 rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)); | 565 rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)); |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 for (int i = 0; i < kBindRetries; ++i) { | 819 for (int i = 0; i < kBindRetries; ++i) { |
| 819 int rv = DoBind(IPEndPoint(address, | 820 int rv = DoBind(IPEndPoint(address, |
| 820 rand_int_cb_.Run(kPortStart, kPortEnd))); | 821 rand_int_cb_.Run(kPortStart, kPortEnd))); |
| 821 if (rv != ERR_ADDRESS_IN_USE) | 822 if (rv != ERR_ADDRESS_IN_USE) |
| 822 return rv; | 823 return rv; |
| 823 } | 824 } |
| 824 return DoBind(IPEndPoint(address, 0)); | 825 return DoBind(IPEndPoint(address, 0)); |
| 825 } | 826 } |
| 826 | 827 |
| 827 int UDPSocketPosix::JoinGroup(const IPAddress& group_address) const { | 828 int UDPSocketPosix::JoinGroup(const IPAddress& group_address) const { |
| 828 DCHECK(CalledOnValidThread()); | 829 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 829 if (!is_connected()) | 830 if (!is_connected()) |
| 830 return ERR_SOCKET_NOT_CONNECTED; | 831 return ERR_SOCKET_NOT_CONNECTED; |
| 831 | 832 |
| 832 switch (group_address.size()) { | 833 switch (group_address.size()) { |
| 833 case IPAddress::kIPv4AddressSize: { | 834 case IPAddress::kIPv4AddressSize: { |
| 834 if (addr_family_ != AF_INET) | 835 if (addr_family_ != AF_INET) |
| 835 return ERR_ADDRESS_INVALID; | 836 return ERR_ADDRESS_INVALID; |
| 836 | 837 |
| 837 #if !defined(OS_MACOSX) | 838 #if !defined(OS_MACOSX) |
| 838 ip_mreqn mreq; | 839 ip_mreqn mreq; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 866 return MapSystemError(errno); | 867 return MapSystemError(errno); |
| 867 return OK; | 868 return OK; |
| 868 } | 869 } |
| 869 default: | 870 default: |
| 870 NOTREACHED() << "Invalid address family"; | 871 NOTREACHED() << "Invalid address family"; |
| 871 return ERR_ADDRESS_INVALID; | 872 return ERR_ADDRESS_INVALID; |
| 872 } | 873 } |
| 873 } | 874 } |
| 874 | 875 |
| 875 int UDPSocketPosix::LeaveGroup(const IPAddress& group_address) const { | 876 int UDPSocketPosix::LeaveGroup(const IPAddress& group_address) const { |
| 876 DCHECK(CalledOnValidThread()); | 877 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 877 | 878 |
| 878 if (!is_connected()) | 879 if (!is_connected()) |
| 879 return ERR_SOCKET_NOT_CONNECTED; | 880 return ERR_SOCKET_NOT_CONNECTED; |
| 880 | 881 |
| 881 switch (group_address.size()) { | 882 switch (group_address.size()) { |
| 882 case IPAddress::kIPv4AddressSize: { | 883 case IPAddress::kIPv4AddressSize: { |
| 883 if (addr_family_ != AF_INET) | 884 if (addr_family_ != AF_INET) |
| 884 return ERR_ADDRESS_INVALID; | 885 return ERR_ADDRESS_INVALID; |
| 885 ip_mreq mreq; | 886 ip_mreq mreq; |
| 886 mreq.imr_interface.s_addr = INADDR_ANY; | 887 mreq.imr_interface.s_addr = INADDR_ANY; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 905 return MapSystemError(errno); | 906 return MapSystemError(errno); |
| 906 return OK; | 907 return OK; |
| 907 } | 908 } |
| 908 default: | 909 default: |
| 909 NOTREACHED() << "Invalid address family"; | 910 NOTREACHED() << "Invalid address family"; |
| 910 return ERR_ADDRESS_INVALID; | 911 return ERR_ADDRESS_INVALID; |
| 911 } | 912 } |
| 912 } | 913 } |
| 913 | 914 |
| 914 int UDPSocketPosix::SetMulticastInterface(uint32_t interface_index) { | 915 int UDPSocketPosix::SetMulticastInterface(uint32_t interface_index) { |
| 915 DCHECK(CalledOnValidThread()); | 916 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 916 if (is_connected()) | 917 if (is_connected()) |
| 917 return ERR_SOCKET_IS_CONNECTED; | 918 return ERR_SOCKET_IS_CONNECTED; |
| 918 multicast_interface_ = interface_index; | 919 multicast_interface_ = interface_index; |
| 919 return OK; | 920 return OK; |
| 920 } | 921 } |
| 921 | 922 |
| 922 int UDPSocketPosix::SetMulticastTimeToLive(int time_to_live) { | 923 int UDPSocketPosix::SetMulticastTimeToLive(int time_to_live) { |
| 923 DCHECK(CalledOnValidThread()); | 924 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 924 if (is_connected()) | 925 if (is_connected()) |
| 925 return ERR_SOCKET_IS_CONNECTED; | 926 return ERR_SOCKET_IS_CONNECTED; |
| 926 | 927 |
| 927 if (time_to_live < 0 || time_to_live > 255) | 928 if (time_to_live < 0 || time_to_live > 255) |
| 928 return ERR_INVALID_ARGUMENT; | 929 return ERR_INVALID_ARGUMENT; |
| 929 multicast_time_to_live_ = time_to_live; | 930 multicast_time_to_live_ = time_to_live; |
| 930 return OK; | 931 return OK; |
| 931 } | 932 } |
| 932 | 933 |
| 933 int UDPSocketPosix::SetMulticastLoopbackMode(bool loopback) { | 934 int UDPSocketPosix::SetMulticastLoopbackMode(bool loopback) { |
| 934 DCHECK(CalledOnValidThread()); | 935 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
| 935 if (is_connected()) | 936 if (is_connected()) |
| 936 return ERR_SOCKET_IS_CONNECTED; | 937 return ERR_SOCKET_IS_CONNECTED; |
| 937 | 938 |
| 938 if (loopback) | 939 if (loopback) |
| 939 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP; | 940 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP; |
| 940 else | 941 else |
| 941 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP; | 942 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP; |
| 942 return OK; | 943 return OK; |
| 943 } | 944 } |
| 944 | 945 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 955 rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_TCLASS, | 956 rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_TCLASS, |
| 956 &dscp_and_ecn, sizeof(dscp_and_ecn)); | 957 &dscp_and_ecn, sizeof(dscp_and_ecn)); |
| 957 } | 958 } |
| 958 if (rv < 0) | 959 if (rv < 0) |
| 959 return MapSystemError(errno); | 960 return MapSystemError(errno); |
| 960 | 961 |
| 961 return OK; | 962 return OK; |
| 962 } | 963 } |
| 963 | 964 |
| 964 void UDPSocketPosix::DetachFromThread() { | 965 void UDPSocketPosix::DetachFromThread() { |
| 965 base::NonThreadSafe::DetachFromThread(); | 966 DETACH_FROM_THREAD(thread_checker_); |
| 966 } | 967 } |
| 967 | 968 |
| 968 } // namespace net | 969 } // namespace net |
| OLD | NEW |