OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) |
6 | 6 |
7 #include "platform/globals.h" | 7 #include "platform/globals.h" |
8 #if defined(HOST_OS_LINUX) | 8 #if defined(HOST_OS_LINUX) |
9 | 9 |
10 #include "bin/socket_base.h" | 10 #include "bin/socket_base.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 SocketAddress::SocketAddress(struct sockaddr* sa) { | 31 SocketAddress::SocketAddress(struct sockaddr* sa) { |
32 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); | 32 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); |
33 if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), | 33 if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), |
34 as_string_, INET6_ADDRSTRLEN)) { | 34 as_string_, INET6_ADDRSTRLEN)) { |
35 as_string_[0] = 0; | 35 as_string_[0] = 0; |
36 } | 36 } |
37 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa)); | 37 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa)); |
38 memmove(reinterpret_cast<void*>(&addr_), sa, salen); | 38 memmove(reinterpret_cast<void*>(&addr_), sa, salen); |
39 } | 39 } |
40 | 40 |
41 | |
42 bool SocketBase::Initialize() { | 41 bool SocketBase::Initialize() { |
43 // Nothing to do on Linux. | 42 // Nothing to do on Linux. |
44 return true; | 43 return true; |
45 } | 44 } |
46 | 45 |
47 | |
48 bool SocketBase::FormatNumericAddress(const RawAddr& addr, | 46 bool SocketBase::FormatNumericAddress(const RawAddr& addr, |
49 char* address, | 47 char* address, |
50 int len) { | 48 int len) { |
51 socklen_t salen = SocketAddress::GetAddrLength(addr); | 49 socklen_t salen = SocketAddress::GetAddrLength(addr); |
52 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL, | 50 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL, |
53 0, NI_NUMERICHOST) == 0)); | 51 0, NI_NUMERICHOST) == 0)); |
54 } | 52 } |
55 | 53 |
56 | |
57 bool SocketBase::IsBindError(intptr_t error_number) { | 54 bool SocketBase::IsBindError(intptr_t error_number) { |
58 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || | 55 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || |
59 error_number == EINVAL; | 56 error_number == EINVAL; |
60 } | 57 } |
61 | 58 |
62 | |
63 intptr_t SocketBase::Available(intptr_t fd) { | 59 intptr_t SocketBase::Available(intptr_t fd) { |
64 return FDUtils::AvailableBytes(fd); | 60 return FDUtils::AvailableBytes(fd); |
65 } | 61 } |
66 | 62 |
67 | |
68 intptr_t SocketBase::Read(intptr_t fd, | 63 intptr_t SocketBase::Read(intptr_t fd, |
69 void* buffer, | 64 void* buffer, |
70 intptr_t num_bytes, | 65 intptr_t num_bytes, |
71 SocketOpKind sync) { | 66 SocketOpKind sync) { |
72 ASSERT(fd >= 0); | 67 ASSERT(fd >= 0); |
73 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); | 68 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); |
74 ASSERT(EAGAIN == EWOULDBLOCK); | 69 ASSERT(EAGAIN == EWOULDBLOCK); |
75 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { | 70 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { |
76 // If the read would block we need to retry and therefore return 0 | 71 // If the read would block we need to retry and therefore return 0 |
77 // as the number of bytes written. | 72 // as the number of bytes written. |
78 read_bytes = 0; | 73 read_bytes = 0; |
79 } | 74 } |
80 return read_bytes; | 75 return read_bytes; |
81 } | 76 } |
82 | 77 |
83 | |
84 intptr_t SocketBase::RecvFrom(intptr_t fd, | 78 intptr_t SocketBase::RecvFrom(intptr_t fd, |
85 void* buffer, | 79 void* buffer, |
86 intptr_t num_bytes, | 80 intptr_t num_bytes, |
87 RawAddr* addr, | 81 RawAddr* addr, |
88 SocketOpKind sync) { | 82 SocketOpKind sync) { |
89 ASSERT(fd >= 0); | 83 ASSERT(fd >= 0); |
90 socklen_t addr_len = sizeof(addr->ss); | 84 socklen_t addr_len = sizeof(addr->ss); |
91 ssize_t read_bytes = TEMP_FAILURE_RETRY( | 85 ssize_t read_bytes = TEMP_FAILURE_RETRY( |
92 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); | 86 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); |
93 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { | 87 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { |
94 // If the read would block we need to retry and therefore return 0 | 88 // If the read would block we need to retry and therefore return 0 |
95 // as the number of bytes written. | 89 // as the number of bytes written. |
96 read_bytes = 0; | 90 read_bytes = 0; |
97 } | 91 } |
98 return read_bytes; | 92 return read_bytes; |
99 } | 93 } |
100 | 94 |
101 | |
102 intptr_t SocketBase::Write(intptr_t fd, | 95 intptr_t SocketBase::Write(intptr_t fd, |
103 const void* buffer, | 96 const void* buffer, |
104 intptr_t num_bytes, | 97 intptr_t num_bytes, |
105 SocketOpKind sync) { | 98 SocketOpKind sync) { |
106 ASSERT(fd >= 0); | 99 ASSERT(fd >= 0); |
107 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); | 100 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); |
108 ASSERT(EAGAIN == EWOULDBLOCK); | 101 ASSERT(EAGAIN == EWOULDBLOCK); |
109 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { | 102 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { |
110 // If the would block we need to retry and therefore return 0 as | 103 // If the would block we need to retry and therefore return 0 as |
111 // the number of bytes written. | 104 // the number of bytes written. |
112 written_bytes = 0; | 105 written_bytes = 0; |
113 } | 106 } |
114 return written_bytes; | 107 return written_bytes; |
115 } | 108 } |
116 | 109 |
117 | |
118 intptr_t SocketBase::SendTo(intptr_t fd, | 110 intptr_t SocketBase::SendTo(intptr_t fd, |
119 const void* buffer, | 111 const void* buffer, |
120 intptr_t num_bytes, | 112 intptr_t num_bytes, |
121 const RawAddr& addr, | 113 const RawAddr& addr, |
122 SocketOpKind sync) { | 114 SocketOpKind sync) { |
123 ASSERT(fd >= 0); | 115 ASSERT(fd >= 0); |
124 ssize_t written_bytes = | 116 ssize_t written_bytes = |
125 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr, | 117 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr, |
126 SocketAddress::GetAddrLength(addr))); | 118 SocketAddress::GetAddrLength(addr))); |
127 ASSERT(EAGAIN == EWOULDBLOCK); | 119 ASSERT(EAGAIN == EWOULDBLOCK); |
128 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { | 120 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { |
129 // If the would block we need to retry and therefore return 0 as | 121 // If the would block we need to retry and therefore return 0 as |
130 // the number of bytes written. | 122 // the number of bytes written. |
131 written_bytes = 0; | 123 written_bytes = 0; |
132 } | 124 } |
133 return written_bytes; | 125 return written_bytes; |
134 } | 126 } |
135 | 127 |
136 | |
137 intptr_t SocketBase::GetPort(intptr_t fd) { | 128 intptr_t SocketBase::GetPort(intptr_t fd) { |
138 ASSERT(fd >= 0); | 129 ASSERT(fd >= 0); |
139 RawAddr raw; | 130 RawAddr raw; |
140 socklen_t size = sizeof(raw); | 131 socklen_t size = sizeof(raw); |
141 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { | 132 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { |
142 return 0; | 133 return 0; |
143 } | 134 } |
144 return SocketAddress::GetAddrPort(raw); | 135 return SocketAddress::GetAddrPort(raw); |
145 } | 136 } |
146 | 137 |
147 | |
148 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) { | 138 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) { |
149 ASSERT(fd >= 0); | 139 ASSERT(fd >= 0); |
150 RawAddr raw; | 140 RawAddr raw; |
151 socklen_t size = sizeof(raw); | 141 socklen_t size = sizeof(raw); |
152 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { | 142 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { |
153 return NULL; | 143 return NULL; |
154 } | 144 } |
155 *port = SocketAddress::GetAddrPort(raw); | 145 *port = SocketAddress::GetAddrPort(raw); |
156 return new SocketAddress(&raw.addr); | 146 return new SocketAddress(&raw.addr); |
157 } | 147 } |
158 | 148 |
159 | |
160 void SocketBase::GetError(intptr_t fd, OSError* os_error) { | 149 void SocketBase::GetError(intptr_t fd, OSError* os_error) { |
161 int len = sizeof(errno); | 150 int len = sizeof(errno); |
162 int err = 0; | 151 int err = 0; |
163 VOID_NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, | 152 VOID_NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, |
164 reinterpret_cast<socklen_t*>(&len))); | 153 reinterpret_cast<socklen_t*>(&len))); |
165 errno = err; | 154 errno = err; |
166 os_error->SetCodeAndMessage(OSError::kSystem, errno); | 155 os_error->SetCodeAndMessage(OSError::kSystem, errno); |
167 } | 156 } |
168 | 157 |
169 | |
170 int SocketBase::GetType(intptr_t fd) { | 158 int SocketBase::GetType(intptr_t fd) { |
171 struct stat64 buf; | 159 struct stat64 buf; |
172 int result = TEMP_FAILURE_RETRY(fstat64(fd, &buf)); | 160 int result = TEMP_FAILURE_RETRY(fstat64(fd, &buf)); |
173 if (result == -1) { | 161 if (result == -1) { |
174 return -1; | 162 return -1; |
175 } | 163 } |
176 if (S_ISCHR(buf.st_mode)) { | 164 if (S_ISCHR(buf.st_mode)) { |
177 return File::kTerminal; | 165 return File::kTerminal; |
178 } | 166 } |
179 if (S_ISFIFO(buf.st_mode)) { | 167 if (S_ISFIFO(buf.st_mode)) { |
180 return File::kPipe; | 168 return File::kPipe; |
181 } | 169 } |
182 if (S_ISREG(buf.st_mode)) { | 170 if (S_ISREG(buf.st_mode)) { |
183 return File::kFile; | 171 return File::kFile; |
184 } | 172 } |
185 return File::kOther; | 173 return File::kOther; |
186 } | 174 } |
187 | 175 |
188 | |
189 intptr_t SocketBase::GetStdioHandle(intptr_t num) { | 176 intptr_t SocketBase::GetStdioHandle(intptr_t num) { |
190 return num; | 177 return num; |
191 } | 178 } |
192 | 179 |
193 | |
194 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host, | 180 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host, |
195 int type, | 181 int type, |
196 OSError** os_error) { | 182 OSError** os_error) { |
197 // Perform a name lookup for a host name. | 183 // Perform a name lookup for a host name. |
198 struct addrinfo hints; | 184 struct addrinfo hints; |
199 memset(&hints, 0, sizeof(hints)); | 185 memset(&hints, 0, sizeof(hints)); |
200 hints.ai_family = SocketAddress::FromType(type); | 186 hints.ai_family = SocketAddress::FromType(type); |
201 hints.ai_socktype = SOCK_STREAM; | 187 hints.ai_socktype = SOCK_STREAM; |
202 hints.ai_flags = AI_ADDRCONFIG; | 188 hints.ai_flags = AI_ADDRCONFIG; |
203 hints.ai_protocol = IPPROTO_TCP; | 189 hints.ai_protocol = IPPROTO_TCP; |
(...skipping 22 matching lines...) Expand all Loading... |
226 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { | 212 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { |
227 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { | 213 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { |
228 addresses->SetAt(i, new SocketAddress(c->ai_addr)); | 214 addresses->SetAt(i, new SocketAddress(c->ai_addr)); |
229 i++; | 215 i++; |
230 } | 216 } |
231 } | 217 } |
232 freeaddrinfo(info); | 218 freeaddrinfo(info); |
233 return addresses; | 219 return addresses; |
234 } | 220 } |
235 | 221 |
236 | |
237 bool SocketBase::ReverseLookup(const RawAddr& addr, | 222 bool SocketBase::ReverseLookup(const RawAddr& addr, |
238 char* host, | 223 char* host, |
239 intptr_t host_len, | 224 intptr_t host_len, |
240 OSError** os_error) { | 225 OSError** os_error) { |
241 ASSERT(host_len >= NI_MAXHOST); | 226 ASSERT(host_len >= NI_MAXHOST); |
242 int status = NO_RETRY_EXPECTED( | 227 int status = NO_RETRY_EXPECTED( |
243 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, | 228 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, |
244 host_len, NULL, 0, NI_NAMEREQD)); | 229 host_len, NULL, 0, NI_NAMEREQD)); |
245 if (status != 0) { | 230 if (status != 0) { |
246 ASSERT(*os_error == NULL); | 231 ASSERT(*os_error == NULL); |
247 *os_error = | 232 *os_error = |
248 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); | 233 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); |
249 return false; | 234 return false; |
250 } | 235 } |
251 return true; | 236 return true; |
252 } | 237 } |
253 | 238 |
254 | |
255 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) { | 239 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) { |
256 int result; | 240 int result; |
257 if (type == SocketAddress::TYPE_IPV4) { | 241 if (type == SocketAddress::TYPE_IPV4) { |
258 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr)); | 242 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr)); |
259 } else { | 243 } else { |
260 ASSERT(type == SocketAddress::TYPE_IPV6); | 244 ASSERT(type == SocketAddress::TYPE_IPV6); |
261 result = | 245 result = |
262 NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr)); | 246 NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr)); |
263 } | 247 } |
264 return (result == 1); | 248 return (result == 1); |
265 } | 249 } |
266 | 250 |
267 | |
268 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { | 251 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { |
269 if (ifa->ifa_addr == NULL) { | 252 if (ifa->ifa_addr == NULL) { |
270 // OpenVPN's virtual device tun0. | 253 // OpenVPN's virtual device tun0. |
271 return false; | 254 return false; |
272 } | 255 } |
273 int family = ifa->ifa_addr->sa_family; | 256 int family = ifa->ifa_addr->sa_family; |
274 return ((lookup_family == family) || | 257 return ((lookup_family == family) || |
275 (((lookup_family == AF_UNSPEC) && | 258 (((lookup_family == AF_UNSPEC) && |
276 ((family == AF_INET) || (family == AF_INET6))))); | 259 ((family == AF_INET) || (family == AF_INET6))))); |
277 } | 260 } |
278 | 261 |
279 | |
280 bool SocketBase::ListInterfacesSupported() { | 262 bool SocketBase::ListInterfacesSupported() { |
281 return true; | 263 return true; |
282 } | 264 } |
283 | 265 |
284 | |
285 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( | 266 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( |
286 int type, | 267 int type, |
287 OSError** os_error) { | 268 OSError** os_error) { |
288 struct ifaddrs* ifaddr; | 269 struct ifaddrs* ifaddr; |
289 | 270 |
290 int status = NO_RETRY_EXPECTED(getifaddrs(&ifaddr)); | 271 int status = NO_RETRY_EXPECTED(getifaddrs(&ifaddr)); |
291 if (status != 0) { | 272 if (status != 0) { |
292 ASSERT(*os_error == NULL); | 273 ASSERT(*os_error == NULL); |
293 *os_error = | 274 *os_error = |
294 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); | 275 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); |
(...skipping 18 matching lines...) Expand all Loading... |
313 addresses->SetAt( | 294 addresses->SetAt( |
314 i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name, | 295 i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name, |
315 if_nametoindex(ifa->ifa_name))); | 296 if_nametoindex(ifa->ifa_name))); |
316 i++; | 297 i++; |
317 } | 298 } |
318 } | 299 } |
319 freeifaddrs(ifaddr); | 300 freeifaddrs(ifaddr); |
320 return addresses; | 301 return addresses; |
321 } | 302 } |
322 | 303 |
323 | |
324 void SocketBase::Close(intptr_t fd) { | 304 void SocketBase::Close(intptr_t fd) { |
325 ASSERT(fd >= 0); | 305 ASSERT(fd >= 0); |
326 VOID_TEMP_FAILURE_RETRY(close(fd)); | 306 VOID_TEMP_FAILURE_RETRY(close(fd)); |
327 } | 307 } |
328 | 308 |
329 | |
330 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) { | 309 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) { |
331 int on; | 310 int on; |
332 socklen_t len = sizeof(on); | 311 socklen_t len = sizeof(on); |
333 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, | 312 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, |
334 reinterpret_cast<void*>(&on), &len)); | 313 reinterpret_cast<void*>(&on), &len)); |
335 if (err == 0) { | 314 if (err == 0) { |
336 *enabled = (on == 1); | 315 *enabled = (on == 1); |
337 } | 316 } |
338 return (err == 0); | 317 return (err == 0); |
339 } | 318 } |
340 | 319 |
341 | |
342 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) { | 320 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) { |
343 int on = enabled ? 1 : 0; | 321 int on = enabled ? 1 : 0; |
344 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, | 322 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, |
345 reinterpret_cast<char*>(&on), | 323 reinterpret_cast<char*>(&on), |
346 sizeof(on))) == 0; | 324 sizeof(on))) == 0; |
347 } | 325 } |
348 | 326 |
349 | |
350 bool SocketBase::GetMulticastLoop(intptr_t fd, | 327 bool SocketBase::GetMulticastLoop(intptr_t fd, |
351 intptr_t protocol, | 328 intptr_t protocol, |
352 bool* enabled) { | 329 bool* enabled) { |
353 uint8_t on; | 330 uint8_t on; |
354 socklen_t len = sizeof(on); | 331 socklen_t len = sizeof(on); |
355 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 332 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
356 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP | 333 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP |
357 : IPV6_MULTICAST_LOOP; | 334 : IPV6_MULTICAST_LOOP; |
358 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, | 335 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, |
359 reinterpret_cast<char*>(&on), &len)) == 0) { | 336 reinterpret_cast<char*>(&on), &len)) == 0) { |
360 *enabled = (on == 1); | 337 *enabled = (on == 1); |
361 return true; | 338 return true; |
362 } | 339 } |
363 return false; | 340 return false; |
364 } | 341 } |
365 | 342 |
366 | |
367 bool SocketBase::SetMulticastLoop(intptr_t fd, | 343 bool SocketBase::SetMulticastLoop(intptr_t fd, |
368 intptr_t protocol, | 344 intptr_t protocol, |
369 bool enabled) { | 345 bool enabled) { |
370 int on = enabled ? 1 : 0; | 346 int on = enabled ? 1 : 0; |
371 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 347 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
372 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP | 348 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP |
373 : IPV6_MULTICAST_LOOP; | 349 : IPV6_MULTICAST_LOOP; |
374 return NO_RETRY_EXPECTED(setsockopt( | 350 return NO_RETRY_EXPECTED(setsockopt( |
375 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) == | 351 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) == |
376 0; | 352 0; |
377 } | 353 } |
378 | 354 |
379 | |
380 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { | 355 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { |
381 uint8_t v; | 356 uint8_t v; |
382 socklen_t len = sizeof(v); | 357 socklen_t len = sizeof(v); |
383 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 358 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
384 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL | 359 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL |
385 : IPV6_MULTICAST_HOPS; | 360 : IPV6_MULTICAST_HOPS; |
386 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, | 361 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, |
387 reinterpret_cast<char*>(&v), &len)) == 0) { | 362 reinterpret_cast<char*>(&v), &len)) == 0) { |
388 *value = v; | 363 *value = v; |
389 return true; | 364 return true; |
390 } | 365 } |
391 return false; | 366 return false; |
392 } | 367 } |
393 | 368 |
394 | |
395 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { | 369 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { |
396 int v = value; | 370 int v = value; |
397 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 371 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
398 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL | 372 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL |
399 : IPV6_MULTICAST_HOPS; | 373 : IPV6_MULTICAST_HOPS; |
400 return NO_RETRY_EXPECTED(setsockopt( | 374 return NO_RETRY_EXPECTED(setsockopt( |
401 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0; | 375 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0; |
402 } | 376 } |
403 | 377 |
404 | |
405 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) { | 378 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) { |
406 int on; | 379 int on; |
407 socklen_t len = sizeof(on); | 380 socklen_t len = sizeof(on); |
408 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST, | 381 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST, |
409 reinterpret_cast<char*>(&on), &len)); | 382 reinterpret_cast<char*>(&on), &len)); |
410 if (err == 0) { | 383 if (err == 0) { |
411 *enabled = (on == 1); | 384 *enabled = (on == 1); |
412 } | 385 } |
413 return (err == 0); | 386 return (err == 0); |
414 } | 387 } |
415 | 388 |
416 | |
417 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) { | 389 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) { |
418 int on = enabled ? 1 : 0; | 390 int on = enabled ? 1 : 0; |
419 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, | 391 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, |
420 reinterpret_cast<char*>(&on), | 392 reinterpret_cast<char*>(&on), |
421 sizeof(on))) == 0; | 393 sizeof(on))) == 0; |
422 } | 394 } |
423 | 395 |
424 | |
425 bool SocketBase::JoinMulticast(intptr_t fd, | 396 bool SocketBase::JoinMulticast(intptr_t fd, |
426 const RawAddr& addr, | 397 const RawAddr& addr, |
427 const RawAddr&, | 398 const RawAddr&, |
428 int interfaceIndex) { | 399 int interfaceIndex) { |
429 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | 400 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
430 struct group_req mreq; | 401 struct group_req mreq; |
431 mreq.gr_interface = interfaceIndex; | 402 mreq.gr_interface = interfaceIndex; |
432 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); | 403 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); |
433 return NO_RETRY_EXPECTED( | 404 return NO_RETRY_EXPECTED( |
434 setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; | 405 setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; |
435 } | 406 } |
436 | 407 |
437 | |
438 bool SocketBase::LeaveMulticast(intptr_t fd, | 408 bool SocketBase::LeaveMulticast(intptr_t fd, |
439 const RawAddr& addr, | 409 const RawAddr& addr, |
440 const RawAddr&, | 410 const RawAddr&, |
441 int interfaceIndex) { | 411 int interfaceIndex) { |
442 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | 412 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
443 struct group_req mreq; | 413 struct group_req mreq; |
444 mreq.gr_interface = interfaceIndex; | 414 mreq.gr_interface = interfaceIndex; |
445 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); | 415 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); |
446 return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, | 416 return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, |
447 sizeof(mreq))) == 0; | 417 sizeof(mreq))) == 0; |
448 } | 418 } |
449 | 419 |
450 } // namespace bin | 420 } // namespace bin |
451 } // namespace dart | 421 } // namespace dart |
452 | 422 |
453 #endif // defined(HOST_OS_LINUX) | 423 #endif // defined(HOST_OS_LINUX) |
454 | 424 |
455 #endif // !defined(DART_IO_DISABLED) | 425 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |