Chromium Code Reviews| 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_libevent.h" | 5 #include "net/udp/udp_socket_libevent.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 <netdb.h> | 10 #include <netdb.h> |
| 10 #include <net/if.h> | |
| 11 #include <netinet/in.h> | 11 #include <netinet/in.h> |
| 12 #include <sys/ioctl.h> | 12 #include <sys/ioctl.h> |
| 13 #include <sys/socket.h> | 13 #include <sys/socket.h> |
| 14 | 14 |
| 15 #include "base/callback.h" | 15 #include "base/callback.h" |
| 16 #include "base/debug/alias.h" | 16 #include "base/debug/alias.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
| 19 #include "base/metrics/sparse_histogram.h" | 19 #include "base/metrics/sparse_histogram.h" |
| 20 #include "base/posix/eintr_wrapper.h" | 20 #include "base/posix/eintr_wrapper.h" |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 49 ifr.ifr_addr.sa_family = AF_INET; | 49 ifr.ifr_addr.sa_family = AF_INET; |
| 50 if (!if_indextoname(index, ifr.ifr_name)) | 50 if (!if_indextoname(index, ifr.ifr_name)) |
| 51 return MapSystemError(errno); | 51 return MapSystemError(errno); |
| 52 int rv = ioctl(socket, SIOCGIFADDR, &ifr); | 52 int rv = ioctl(socket, SIOCGIFADDR, &ifr); |
| 53 if (rv == -1) | 53 if (rv == -1) |
| 54 return MapSystemError(errno); | 54 return MapSystemError(errno); |
| 55 *address = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr)->sin_addr.s_addr; | 55 *address = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr)->sin_addr.s_addr; |
| 56 return OK; | 56 return OK; |
| 57 } | 57 } |
| 58 | 58 |
| 59 // On OSX the file descriptor is guarded to detect the cause of | |
| 60 // crbug.com/461246. sys/guarded.h is not included in the SDK, so the API needs | |
| 61 // to be defined here. | |
|
Mark Mentovai
2015/04/02 14:37:06
Drive the point home by saying in the comment that
Sergey Ulanov
2015/04/02 18:05:42
Added TODO to remove it.
| |
| 62 | |
| 63 typedef uint64_t guardid_t; | |
| 64 | |
| 65 int guarded_close_np(int fd, const guardid_t *guard) { | |
| 66 return syscall(442, fd, guard); | |
|
Mark Mentovai
2015/04/02 14:37:06
This is only available in 10.9 and 10.10. It’ll be
Sergey Ulanov
2015/04/02 18:05:42
Done.
| |
| 67 } | |
| 68 int change_fdguard_np(int fd, const guardid_t *guard, u_int flags, | |
| 69 const guardid_t *nguard, u_int nflags, int *fdflagsp) { | |
| 70 return syscall(444, fd, guard, flags, nguard, nflags, fdflagsp); | |
| 71 } | |
| 72 | |
| 73 const unsigned int GUARD_CLOSE = 1u<<0; | |
| 74 const unsigned int GUARD_DUP = 1u<<1; | |
| 75 | |
| 76 const guardid_t kSocketFdGuard = 0xD712BC0BC9A4EAD4; | |
| 77 | |
| 59 #endif // OS_MACOSX | 78 #endif // OS_MACOSX |
| 60 | 79 |
| 61 } // namespace | 80 } // namespace |
| 62 | 81 |
| 63 UDPSocketLibevent::UDPSocketLibevent( | 82 UDPSocketLibevent::UDPSocketLibevent( |
| 64 DatagramSocket::BindType bind_type, | 83 DatagramSocket::BindType bind_type, |
| 65 const RandIntCallback& rand_int_cb, | 84 const RandIntCallback& rand_int_cb, |
| 66 net::NetLog* net_log, | 85 net::NetLog* net_log, |
| 67 const net::NetLog::Source& source) | 86 const net::NetLog::Source& source) |
| 68 : socket_(kInvalidSocket), | 87 : socket_(kInvalidSocket), |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 91 } | 110 } |
| 92 | 111 |
| 93 int UDPSocketLibevent::Open(AddressFamily address_family) { | 112 int UDPSocketLibevent::Open(AddressFamily address_family) { |
| 94 DCHECK(CalledOnValidThread()); | 113 DCHECK(CalledOnValidThread()); |
| 95 DCHECK_EQ(socket_, kInvalidSocket); | 114 DCHECK_EQ(socket_, kInvalidSocket); |
| 96 | 115 |
| 97 addr_family_ = ConvertAddressFamily(address_family); | 116 addr_family_ = ConvertAddressFamily(address_family); |
| 98 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0); | 117 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0); |
| 99 if (socket_ == kInvalidSocket) | 118 if (socket_ == kInvalidSocket) |
| 100 return MapSystemError(errno); | 119 return MapSystemError(errno); |
| 120 #if defined(OS_MACOSX) | |
| 121 PCHECK(change_fdguard_np(socket_, NULL, 0, &kSocketFdGuard, | |
| 122 GUARD_CLOSE | GUARD_DUP, NULL) == 0); | |
| 123 #endif // OS_MACOSX | |
| 101 if (SetNonBlocking(socket_)) { | 124 if (SetNonBlocking(socket_)) { |
| 102 const int err = MapSystemError(errno); | 125 const int err = MapSystemError(errno); |
| 103 Close(); | 126 Close(); |
| 104 return err; | 127 return err; |
| 105 } | 128 } |
| 106 return OK; | 129 return OK; |
| 107 } | 130 } |
| 108 | 131 |
| 109 void UDPSocketLibevent::Close() { | 132 void UDPSocketLibevent::Close() { |
| 110 DCHECK(CalledOnValidThread()); | 133 DCHECK(CalledOnValidThread()); |
| 111 | 134 |
| 112 if (socket_ == kInvalidSocket) | 135 if (socket_ == kInvalidSocket) |
| 113 return; | 136 return; |
| 114 | 137 |
| 115 // Zero out any pending read/write callback state. | 138 // Zero out any pending read/write callback state. |
| 116 read_buf_ = NULL; | 139 read_buf_ = NULL; |
| 117 read_buf_len_ = 0; | 140 read_buf_len_ = 0; |
| 118 read_callback_.Reset(); | 141 read_callback_.Reset(); |
| 119 recv_from_address_ = NULL; | 142 recv_from_address_ = NULL; |
| 120 write_buf_ = NULL; | 143 write_buf_ = NULL; |
| 121 write_buf_len_ = 0; | 144 write_buf_len_ = 0; |
| 122 write_callback_.Reset(); | 145 write_callback_.Reset(); |
| 123 send_to_address_.reset(); | 146 send_to_address_.reset(); |
| 124 | 147 |
| 125 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); | 148 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); |
| 126 DCHECK(ok); | 149 DCHECK(ok); |
| 127 ok = write_socket_watcher_.StopWatchingFileDescriptor(); | 150 ok = write_socket_watcher_.StopWatchingFileDescriptor(); |
| 128 DCHECK(ok); | 151 DCHECK(ok); |
| 129 | 152 |
| 153 #if defined(OS_MACOSX) | |
| 154 PCHECK(IGNORE_EINTR(guarded_close_np(socket_, &kSocketFdGuard)) == 0); | |
| 155 #else | |
| 130 PCHECK(IGNORE_EINTR(close(socket_)) == 0); | 156 PCHECK(IGNORE_EINTR(close(socket_)) == 0); |
| 157 #endif // OS_MACOSX | |
| 131 | 158 |
| 132 socket_ = kInvalidSocket; | 159 socket_ = kInvalidSocket; |
| 133 addr_family_ = 0; | 160 addr_family_ = 0; |
| 134 is_connected_ = false; | 161 is_connected_ = false; |
| 135 } | 162 } |
| 136 | 163 |
| 137 int UDPSocketLibevent::GetPeerAddress(IPEndPoint* address) const { | 164 int UDPSocketLibevent::GetPeerAddress(IPEndPoint* address) const { |
| 138 DCHECK(CalledOnValidThread()); | 165 DCHECK(CalledOnValidThread()); |
| 139 DCHECK(address); | 166 DCHECK(address); |
| 140 if (!is_connected()) | 167 if (!is_connected()) |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 744 return MapSystemError(errno); | 771 return MapSystemError(errno); |
| 745 | 772 |
| 746 return OK; | 773 return OK; |
| 747 } | 774 } |
| 748 | 775 |
| 749 void UDPSocketLibevent::DetachFromThread() { | 776 void UDPSocketLibevent::DetachFromThread() { |
| 750 base::NonThreadSafe::DetachFromThread(); | 777 base::NonThreadSafe::DetachFromThread(); |
| 751 } | 778 } |
| 752 | 779 |
| 753 } // namespace net | 780 } // namespace net |
| OLD | NEW |