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_WINDOWS) | 8 #if defined(HOST_OS_WINDOWS) |
9 | 9 |
10 #include "bin/socket_base.h" | 10 #include "bin/socket_base.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 int err = | 31 int err = |
32 SocketBase::FormatNumericAddress(*raw, as_string_, INET6_ADDRSTRLEN); | 32 SocketBase::FormatNumericAddress(*raw, as_string_, INET6_ADDRSTRLEN); |
33 | 33 |
34 if (err != 0) { | 34 if (err != 0) { |
35 as_string_[0] = 0; | 35 as_string_[0] = 0; |
36 } | 36 } |
37 memmove(reinterpret_cast<void*>(&addr_), sockaddr, | 37 memmove(reinterpret_cast<void*>(&addr_), sockaddr, |
38 SocketAddress::GetAddrLength(*raw)); | 38 SocketAddress::GetAddrLength(*raw)); |
39 } | 39 } |
40 | 40 |
41 | |
42 static Mutex* init_mutex = new Mutex(); | 41 static Mutex* init_mutex = new Mutex(); |
43 static bool socket_initialized = false; | 42 static bool socket_initialized = false; |
44 | 43 |
45 bool SocketBase::Initialize() { | 44 bool SocketBase::Initialize() { |
46 MutexLocker lock(init_mutex); | 45 MutexLocker lock(init_mutex); |
47 if (socket_initialized) { | 46 if (socket_initialized) { |
48 return true; | 47 return true; |
49 } | 48 } |
50 int err; | 49 int err; |
51 WSADATA winsock_data; | 50 WSADATA winsock_data; |
52 WORD version_requested = MAKEWORD(2, 2); | 51 WORD version_requested = MAKEWORD(2, 2); |
53 err = WSAStartup(version_requested, &winsock_data); | 52 err = WSAStartup(version_requested, &winsock_data); |
54 if (err == 0) { | 53 if (err == 0) { |
55 socket_initialized = true; | 54 socket_initialized = true; |
56 } else { | 55 } else { |
57 Log::PrintErr("Unable to initialize Winsock: %d\n", WSAGetLastError()); | 56 Log::PrintErr("Unable to initialize Winsock: %d\n", WSAGetLastError()); |
58 } | 57 } |
59 return (err == 0); | 58 return (err == 0); |
60 } | 59 } |
61 | 60 |
62 | |
63 bool SocketBase::FormatNumericAddress(const RawAddr& addr, | 61 bool SocketBase::FormatNumericAddress(const RawAddr& addr, |
64 char* address, | 62 char* address, |
65 int len) { | 63 int len) { |
66 socklen_t salen = SocketAddress::GetAddrLength(addr); | 64 socklen_t salen = SocketAddress::GetAddrLength(addr); |
67 DWORD l = len; | 65 DWORD l = len; |
68 RawAddr& raw = const_cast<RawAddr&>(addr); | 66 RawAddr& raw = const_cast<RawAddr&>(addr); |
69 return WSAAddressToStringA(&raw.addr, salen, NULL, address, &l) != 0; | 67 return WSAAddressToStringA(&raw.addr, salen, NULL, address, &l) != 0; |
70 } | 68 } |
71 | 69 |
72 | |
73 intptr_t SocketBase::Available(intptr_t fd) { | 70 intptr_t SocketBase::Available(intptr_t fd) { |
74 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd); | 71 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd); |
75 return client_socket->Available(); | 72 return client_socket->Available(); |
76 } | 73 } |
77 | 74 |
78 | |
79 intptr_t SocketBase::Read(intptr_t fd, | 75 intptr_t SocketBase::Read(intptr_t fd, |
80 void* buffer, | 76 void* buffer, |
81 intptr_t num_bytes, | 77 intptr_t num_bytes, |
82 SocketOpKind sync) { | 78 SocketOpKind sync) { |
83 Handle* handle = reinterpret_cast<Handle*>(fd); | 79 Handle* handle = reinterpret_cast<Handle*>(fd); |
84 return handle->Read(buffer, num_bytes); | 80 return handle->Read(buffer, num_bytes); |
85 } | 81 } |
86 | 82 |
87 | |
88 intptr_t SocketBase::RecvFrom(intptr_t fd, | 83 intptr_t SocketBase::RecvFrom(intptr_t fd, |
89 void* buffer, | 84 void* buffer, |
90 intptr_t num_bytes, | 85 intptr_t num_bytes, |
91 RawAddr* addr, | 86 RawAddr* addr, |
92 SocketOpKind sync) { | 87 SocketOpKind sync) { |
93 Handle* handle = reinterpret_cast<Handle*>(fd); | 88 Handle* handle = reinterpret_cast<Handle*>(fd); |
94 socklen_t addr_len = sizeof(addr->ss); | 89 socklen_t addr_len = sizeof(addr->ss); |
95 return handle->RecvFrom(buffer, num_bytes, &addr->addr, addr_len); | 90 return handle->RecvFrom(buffer, num_bytes, &addr->addr, addr_len); |
96 } | 91 } |
97 | 92 |
98 | |
99 intptr_t SocketBase::Write(intptr_t fd, | 93 intptr_t SocketBase::Write(intptr_t fd, |
100 const void* buffer, | 94 const void* buffer, |
101 intptr_t num_bytes, | 95 intptr_t num_bytes, |
102 SocketOpKind sync) { | 96 SocketOpKind sync) { |
103 Handle* handle = reinterpret_cast<Handle*>(fd); | 97 Handle* handle = reinterpret_cast<Handle*>(fd); |
104 return handle->Write(buffer, num_bytes); | 98 return handle->Write(buffer, num_bytes); |
105 } | 99 } |
106 | 100 |
107 | |
108 intptr_t SocketBase::SendTo(intptr_t fd, | 101 intptr_t SocketBase::SendTo(intptr_t fd, |
109 const void* buffer, | 102 const void* buffer, |
110 intptr_t num_bytes, | 103 intptr_t num_bytes, |
111 const RawAddr& addr, | 104 const RawAddr& addr, |
112 SocketOpKind sync) { | 105 SocketOpKind sync) { |
113 Handle* handle = reinterpret_cast<Handle*>(fd); | 106 Handle* handle = reinterpret_cast<Handle*>(fd); |
114 RawAddr& raw = const_cast<RawAddr&>(addr); | 107 RawAddr& raw = const_cast<RawAddr&>(addr); |
115 return handle->SendTo(buffer, num_bytes, &raw.addr, | 108 return handle->SendTo(buffer, num_bytes, &raw.addr, |
116 SocketAddress::GetAddrLength(addr)); | 109 SocketAddress::GetAddrLength(addr)); |
117 } | 110 } |
118 | 111 |
119 | |
120 intptr_t SocketBase::GetPort(intptr_t fd) { | 112 intptr_t SocketBase::GetPort(intptr_t fd) { |
121 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); | 113 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); |
122 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); | 114 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); |
123 RawAddr raw; | 115 RawAddr raw; |
124 socklen_t size = sizeof(raw); | 116 socklen_t size = sizeof(raw); |
125 if (getsockname(socket_handle->socket(), &raw.addr, &size) == SOCKET_ERROR) { | 117 if (getsockname(socket_handle->socket(), &raw.addr, &size) == SOCKET_ERROR) { |
126 return 0; | 118 return 0; |
127 } | 119 } |
128 return SocketAddress::GetAddrPort(raw); | 120 return SocketAddress::GetAddrPort(raw); |
129 } | 121 } |
130 | 122 |
131 | |
132 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) { | 123 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) { |
133 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); | 124 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); |
134 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); | 125 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); |
135 RawAddr raw; | 126 RawAddr raw; |
136 socklen_t size = sizeof(raw); | 127 socklen_t size = sizeof(raw); |
137 if (getpeername(socket_handle->socket(), &raw.addr, &size)) { | 128 if (getpeername(socket_handle->socket(), &raw.addr, &size)) { |
138 return NULL; | 129 return NULL; |
139 } | 130 } |
140 *port = SocketAddress::GetAddrPort(raw); | 131 *port = SocketAddress::GetAddrPort(raw); |
141 // Clear the port before calling WSAAddressToString as WSAAddressToString | 132 // Clear the port before calling WSAAddressToString as WSAAddressToString |
142 // includes the port in the formatted string. | 133 // includes the port in the formatted string. |
143 SocketAddress::SetAddrPort(&raw, 0); | 134 SocketAddress::SetAddrPort(&raw, 0); |
144 return new SocketAddress(&raw.addr); | 135 return new SocketAddress(&raw.addr); |
145 } | 136 } |
146 | 137 |
147 | |
148 bool SocketBase::IsBindError(intptr_t error_number) { | 138 bool SocketBase::IsBindError(intptr_t error_number) { |
149 return error_number == WSAEADDRINUSE || error_number == WSAEADDRNOTAVAIL || | 139 return error_number == WSAEADDRINUSE || error_number == WSAEADDRNOTAVAIL || |
150 error_number == WSAEINVAL; | 140 error_number == WSAEINVAL; |
151 } | 141 } |
152 | 142 |
153 | |
154 void SocketBase::GetError(intptr_t fd, OSError* os_error) { | 143 void SocketBase::GetError(intptr_t fd, OSError* os_error) { |
155 Handle* handle = reinterpret_cast<Handle*>(fd); | 144 Handle* handle = reinterpret_cast<Handle*>(fd); |
156 os_error->SetCodeAndMessage(OSError::kSystem, handle->last_error()); | 145 os_error->SetCodeAndMessage(OSError::kSystem, handle->last_error()); |
157 } | 146 } |
158 | 147 |
159 | |
160 int SocketBase::GetType(intptr_t fd) { | 148 int SocketBase::GetType(intptr_t fd) { |
161 Handle* handle = reinterpret_cast<Handle*>(fd); | 149 Handle* handle = reinterpret_cast<Handle*>(fd); |
162 switch (GetFileType(handle->handle())) { | 150 switch (GetFileType(handle->handle())) { |
163 case FILE_TYPE_CHAR: | 151 case FILE_TYPE_CHAR: |
164 return File::kTerminal; | 152 return File::kTerminal; |
165 case FILE_TYPE_PIPE: | 153 case FILE_TYPE_PIPE: |
166 return File::kPipe; | 154 return File::kPipe; |
167 case FILE_TYPE_DISK: | 155 case FILE_TYPE_DISK: |
168 return File::kFile; | 156 return File::kFile; |
169 default: | 157 default: |
170 return GetLastError == NO_ERROR ? File::kOther : -1; | 158 return GetLastError == NO_ERROR ? File::kOther : -1; |
171 } | 159 } |
172 } | 160 } |
173 | 161 |
174 | |
175 intptr_t SocketBase::GetStdioHandle(intptr_t num) { | 162 intptr_t SocketBase::GetStdioHandle(intptr_t num) { |
176 if (num != 0) { | 163 if (num != 0) { |
177 return -1; | 164 return -1; |
178 } | 165 } |
179 HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); | 166 HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); |
180 if (handle == INVALID_HANDLE_VALUE) { | 167 if (handle == INVALID_HANDLE_VALUE) { |
181 return -1; | 168 return -1; |
182 } | 169 } |
183 StdHandle* std_handle = StdHandle::Stdin(handle); | 170 StdHandle* std_handle = StdHandle::Stdin(handle); |
184 std_handle->Retain(); | 171 std_handle->Retain(); |
185 std_handle->MarkDoesNotSupportOverlappedIO(); | 172 std_handle->MarkDoesNotSupportOverlappedIO(); |
186 std_handle->EnsureInitialized(EventHandler::delegate()); | 173 std_handle->EnsureInitialized(EventHandler::delegate()); |
187 return reinterpret_cast<intptr_t>(std_handle); | 174 return reinterpret_cast<intptr_t>(std_handle); |
188 } | 175 } |
189 | 176 |
190 | |
191 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host, | 177 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host, |
192 int type, | 178 int type, |
193 OSError** os_error) { | 179 OSError** os_error) { |
194 Initialize(); | 180 Initialize(); |
195 | 181 |
196 // Perform a name lookup for a host name. | 182 // Perform a name lookup for a host name. |
197 struct addrinfo hints; | 183 struct addrinfo hints; |
198 memset(&hints, 0, sizeof(hints)); | 184 memset(&hints, 0, sizeof(hints)); |
199 hints.ai_family = SocketAddress::FromType(type); | 185 hints.ai_family = SocketAddress::FromType(type); |
200 hints.ai_socktype = SOCK_STREAM; | 186 hints.ai_socktype = SOCK_STREAM; |
(...skipping 25 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 = getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, | 227 int status = getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, |
243 host_len, NULL, 0, NI_NAMEREQD); | 228 host_len, NULL, 0, NI_NAMEREQD); |
244 if (status != 0) { | 229 if (status != 0) { |
245 ASSERT(*os_error == NULL); | 230 ASSERT(*os_error == NULL); |
246 DWORD error_code = WSAGetLastError(); | 231 DWORD error_code = WSAGetLastError(); |
247 SetLastError(error_code); | 232 SetLastError(error_code); |
248 *os_error = new OSError(); | 233 *os_error = new OSError(); |
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 Utf8ToWideScope system_address(address); | 241 Utf8ToWideScope system_address(address); |
258 if (type == SocketAddress::TYPE_IPV4) { | 242 if (type == SocketAddress::TYPE_IPV4) { |
259 result = InetPton(AF_INET, system_address.wide(), &addr->in.sin_addr); | 243 result = InetPton(AF_INET, system_address.wide(), &addr->in.sin_addr); |
260 } else { | 244 } else { |
261 ASSERT(type == SocketAddress::TYPE_IPV6); | 245 ASSERT(type == SocketAddress::TYPE_IPV6); |
262 result = InetPton(AF_INET6, system_address.wide(), &addr->in6.sin6_addr); | 246 result = InetPton(AF_INET6, system_address.wide(), &addr->in6.sin6_addr); |
263 } | 247 } |
264 return result == 1; | 248 return result == 1; |
265 } | 249 } |
266 | 250 |
267 | |
268 bool SocketBase::ListInterfacesSupported() { | 251 bool SocketBase::ListInterfacesSupported() { |
269 return true; | 252 return true; |
270 } | 253 } |
271 | 254 |
272 | |
273 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( | 255 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( |
274 int type, | 256 int type, |
275 OSError** os_error) { | 257 OSError** os_error) { |
276 Initialize(); | 258 Initialize(); |
277 | 259 |
278 ULONG size = 0; | 260 ULONG size = 0; |
279 DWORD flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | | 261 DWORD flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | |
280 GAA_FLAG_SKIP_DNS_SERVER; | 262 GAA_FLAG_SKIP_DNS_SERVER; |
281 // Query the size needed. | 263 // Query the size needed. |
282 int status = GetAdaptersAddresses(SocketAddress::FromType(type), flags, NULL, | 264 int status = GetAdaptersAddresses(SocketAddress::FromType(type), flags, NULL, |
(...skipping 29 matching lines...) Expand all Loading... |
312 i, new InterfaceSocketAddress( | 294 i, new InterfaceSocketAddress( |
313 u->Address.lpSockaddr, | 295 u->Address.lpSockaddr, |
314 StringUtilsWin::WideToUtf8(a->FriendlyName), a->Ipv6IfIndex)); | 296 StringUtilsWin::WideToUtf8(a->FriendlyName), a->Ipv6IfIndex)); |
315 i++; | 297 i++; |
316 } | 298 } |
317 } | 299 } |
318 free(addrs); | 300 free(addrs); |
319 return addresses; | 301 return addresses; |
320 } | 302 } |
321 | 303 |
322 | |
323 void SocketBase::Close(intptr_t fd) { | 304 void SocketBase::Close(intptr_t fd) { |
324 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd); | 305 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd); |
325 client_socket->Close(); | 306 client_socket->Close(); |
326 } | 307 } |
327 | 308 |
328 | |
329 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) { | 309 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) { |
330 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 310 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
331 int on; | 311 int on; |
332 socklen_t len = sizeof(on); | 312 socklen_t len = sizeof(on); |
333 int err = getsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY, | 313 int err = getsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY, |
334 reinterpret_cast<char*>(&on), &len); | 314 reinterpret_cast<char*>(&on), &len); |
335 if (err == 0) { | 315 if (err == 0) { |
336 *enabled = (on == 1); | 316 *enabled = (on == 1); |
337 } | 317 } |
338 return (err == 0); | 318 return (err == 0); |
339 } | 319 } |
340 | 320 |
341 | |
342 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) { | 321 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) { |
343 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 322 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
344 int on = enabled ? 1 : 0; | 323 int on = enabled ? 1 : 0; |
345 return setsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY, | 324 return setsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY, |
346 reinterpret_cast<char*>(&on), sizeof(on)) == 0; | 325 reinterpret_cast<char*>(&on), sizeof(on)) == 0; |
347 } | 326 } |
348 | 327 |
349 | |
350 bool SocketBase::GetMulticastLoop(intptr_t fd, | 328 bool SocketBase::GetMulticastLoop(intptr_t fd, |
351 intptr_t protocol, | 329 intptr_t protocol, |
352 bool* enabled) { | 330 bool* enabled) { |
353 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 331 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
354 uint8_t on; | 332 uint8_t on; |
355 socklen_t len = sizeof(on); | 333 socklen_t len = sizeof(on); |
356 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 334 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
357 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP | 335 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP |
358 : IPV6_MULTICAST_LOOP; | 336 : IPV6_MULTICAST_LOOP; |
359 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&on), | 337 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&on), |
360 &len) == 0) { | 338 &len) == 0) { |
361 *enabled = (on == 1); | 339 *enabled = (on == 1); |
362 return true; | 340 return true; |
363 } | 341 } |
364 return false; | 342 return false; |
365 } | 343 } |
366 | 344 |
367 | |
368 bool SocketBase::SetMulticastLoop(intptr_t fd, | 345 bool SocketBase::SetMulticastLoop(intptr_t fd, |
369 intptr_t protocol, | 346 intptr_t protocol, |
370 bool enabled) { | 347 bool enabled) { |
371 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 348 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
372 int on = enabled ? 1 : 0; | 349 int on = enabled ? 1 : 0; |
373 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 350 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
374 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP | 351 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP |
375 : IPV6_MULTICAST_LOOP; | 352 : IPV6_MULTICAST_LOOP; |
376 return setsockopt(handle->socket(), level, optname, | 353 return setsockopt(handle->socket(), level, optname, |
377 reinterpret_cast<char*>(&on), sizeof(on)) == 0; | 354 reinterpret_cast<char*>(&on), sizeof(on)) == 0; |
378 } | 355 } |
379 | 356 |
380 | |
381 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { | 357 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { |
382 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 358 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
383 uint8_t v; | 359 uint8_t v; |
384 socklen_t len = sizeof(v); | 360 socklen_t len = sizeof(v); |
385 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 361 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
386 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL | 362 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL |
387 : IPV6_MULTICAST_HOPS; | 363 : IPV6_MULTICAST_HOPS; |
388 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&v), | 364 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&v), |
389 &len) == 0) { | 365 &len) == 0) { |
390 *value = v; | 366 *value = v; |
391 return true; | 367 return true; |
392 } | 368 } |
393 return false; | 369 return false; |
394 } | 370 } |
395 | 371 |
396 | |
397 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { | 372 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { |
398 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 373 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
399 int v = value; | 374 int v = value; |
400 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 375 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
401 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL | 376 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL |
402 : IPV6_MULTICAST_HOPS; | 377 : IPV6_MULTICAST_HOPS; |
403 return setsockopt(handle->socket(), level, optname, | 378 return setsockopt(handle->socket(), level, optname, |
404 reinterpret_cast<char*>(&v), sizeof(v)) == 0; | 379 reinterpret_cast<char*>(&v), sizeof(v)) == 0; |
405 } | 380 } |
406 | 381 |
407 | |
408 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) { | 382 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) { |
409 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 383 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
410 int on; | 384 int on; |
411 socklen_t len = sizeof(on); | 385 socklen_t len = sizeof(on); |
412 int err = getsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST, | 386 int err = getsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST, |
413 reinterpret_cast<char*>(&on), &len); | 387 reinterpret_cast<char*>(&on), &len); |
414 if (err == 0) { | 388 if (err == 0) { |
415 *enabled = (on == 1); | 389 *enabled = (on == 1); |
416 } | 390 } |
417 return (err == 0); | 391 return (err == 0); |
418 } | 392 } |
419 | 393 |
420 | |
421 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) { | 394 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) { |
422 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 395 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
423 int on = enabled ? 1 : 0; | 396 int on = enabled ? 1 : 0; |
424 return setsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST, | 397 return setsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST, |
425 reinterpret_cast<char*>(&on), sizeof(on)) == 0; | 398 reinterpret_cast<char*>(&on), sizeof(on)) == 0; |
426 } | 399 } |
427 | 400 |
428 | |
429 bool SocketBase::JoinMulticast(intptr_t fd, | 401 bool SocketBase::JoinMulticast(intptr_t fd, |
430 const RawAddr& addr, | 402 const RawAddr& addr, |
431 const RawAddr&, | 403 const RawAddr&, |
432 int interfaceIndex) { | 404 int interfaceIndex) { |
433 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 405 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
434 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | 406 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
435 struct group_req mreq; | 407 struct group_req mreq; |
436 mreq.gr_interface = interfaceIndex; | 408 mreq.gr_interface = interfaceIndex; |
437 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); | 409 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); |
438 return setsockopt(handle->socket(), proto, MCAST_JOIN_GROUP, | 410 return setsockopt(handle->socket(), proto, MCAST_JOIN_GROUP, |
439 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0; | 411 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0; |
440 } | 412 } |
441 | 413 |
442 | |
443 bool SocketBase::LeaveMulticast(intptr_t fd, | 414 bool SocketBase::LeaveMulticast(intptr_t fd, |
444 const RawAddr& addr, | 415 const RawAddr& addr, |
445 const RawAddr&, | 416 const RawAddr&, |
446 int interfaceIndex) { | 417 int interfaceIndex) { |
447 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 418 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
448 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | 419 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
449 struct group_req mreq; | 420 struct group_req mreq; |
450 mreq.gr_interface = interfaceIndex; | 421 mreq.gr_interface = interfaceIndex; |
451 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); | 422 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); |
452 return setsockopt(handle->socket(), proto, MCAST_LEAVE_GROUP, | 423 return setsockopt(handle->socket(), proto, MCAST_LEAVE_GROUP, |
453 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0; | 424 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0; |
454 } | 425 } |
455 | 426 |
456 } // namespace bin | 427 } // namespace bin |
457 } // namespace dart | 428 } // namespace dart |
458 | 429 |
459 #endif // defined(HOST_OS_WINDOWS) | 430 #endif // defined(HOST_OS_WINDOWS) |
460 | 431 |
461 #endif // !defined(DART_IO_DISABLED) | 432 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |