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 #ifndef BIN_SOCKET_H_ | 5 #ifndef BIN_SOCKET_H_ |
6 #define BIN_SOCKET_H_ | 6 #define BIN_SOCKET_H_ |
7 | 7 |
| 8 #include <map> |
| 9 |
8 #include "platform/globals.h" | 10 #include "platform/globals.h" |
9 | 11 |
10 #include "bin/builtin.h" | 12 #include "bin/builtin.h" |
11 #include "bin/dartutils.h" | 13 #include "bin/dartutils.h" |
12 // Declare the OS-specific types ahead of defining the generic class. | 14 // Declare the OS-specific types ahead of defining the generic class. |
13 #if defined(TARGET_OS_ANDROID) | 15 #if defined(TARGET_OS_ANDROID) |
14 #include "bin/socket_android.h" | 16 #include "bin/socket_android.h" |
15 #elif defined(TARGET_OS_LINUX) | 17 #elif defined(TARGET_OS_LINUX) |
16 #include "bin/socket_linux.h" | 18 #include "bin/socket_linux.h" |
17 #elif defined(TARGET_OS_MACOS) | 19 #elif defined(TARGET_OS_MACOS) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 return addr->ss.ss_family == AF_INET6 ? | 71 return addr->ss.ss_family == AF_INET6 ? |
70 sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); | 72 sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); |
71 } | 73 } |
72 | 74 |
73 static intptr_t GetInAddrLength(const RawAddr* addr) { | 75 static intptr_t GetInAddrLength(const RawAddr* addr) { |
74 ASSERT(addr->ss.ss_family == AF_INET || addr->ss.ss_family == AF_INET6); | 76 ASSERT(addr->ss.ss_family == AF_INET || addr->ss.ss_family == AF_INET6); |
75 return addr->ss.ss_family == AF_INET6 ? | 77 return addr->ss.ss_family == AF_INET6 ? |
76 sizeof(struct in6_addr) : sizeof(struct in_addr); | 78 sizeof(struct in6_addr) : sizeof(struct in_addr); |
77 } | 79 } |
78 | 80 |
| 81 static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) { |
| 82 if (a.ss.ss_family == AF_INET) { |
| 83 if (b.ss.ss_family != AF_INET) return false; |
| 84 return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0; |
| 85 } else if (a.ss.ss_family == AF_INET6) { |
| 86 if (b.ss.ss_family != AF_INET6) return false; |
| 87 return memcmp(&a.in6.sin6_addr, |
| 88 &b.in6.sin6_addr, |
| 89 sizeof(a.in6.sin6_addr)) == 0; |
| 90 } else { |
| 91 UNREACHABLE(); |
| 92 return false; |
| 93 } |
| 94 } |
| 95 |
79 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { | 96 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { |
80 Dart_TypedData_Type data_type; | 97 Dart_TypedData_Type data_type; |
81 uint8_t* data = NULL; | 98 uint8_t* data = NULL; |
82 intptr_t len; | 99 intptr_t len; |
83 Dart_Handle result = Dart_TypedDataAcquireData( | 100 Dart_Handle result = Dart_TypedDataAcquireData( |
84 obj, &data_type, reinterpret_cast<void**>(&data), &len); | 101 obj, &data_type, reinterpret_cast<void**>(&data), &len); |
85 if (Dart_IsError(result)) Dart_PropagateError(result); | 102 if (Dart_IsError(result)) Dart_PropagateError(result); |
86 if (data_type != Dart_TypedData_kUint8 || | 103 if (data_type != Dart_TypedData_kUint8 || |
87 (len != sizeof(in_addr) && len != sizeof(in6_addr))) { | 104 (len != sizeof(in_addr) && len != sizeof(in6_addr))) { |
88 Dart_PropagateError( | 105 Dart_PropagateError( |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 | 230 |
214 class Socket { | 231 class Socket { |
215 public: | 232 public: |
216 enum SocketRequest { | 233 enum SocketRequest { |
217 kLookupRequest = 0, | 234 kLookupRequest = 0, |
218 kListInterfacesRequest = 1, | 235 kListInterfacesRequest = 1, |
219 kReverseLookupRequest = 2, | 236 kReverseLookupRequest = 2, |
220 }; | 237 }; |
221 | 238 |
222 static bool Initialize(); | 239 static bool Initialize(); |
| 240 static bool InitializeOS(); |
223 static intptr_t Available(intptr_t fd); | 241 static intptr_t Available(intptr_t fd); |
224 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes); | 242 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes); |
225 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes); | 243 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes); |
226 static intptr_t SendTo( | 244 static intptr_t SendTo( |
227 intptr_t fd, const void* buffer, intptr_t num_bytes, RawAddr addr); | 245 intptr_t fd, const void* buffer, intptr_t num_bytes, RawAddr addr); |
228 static intptr_t RecvFrom( | 246 static intptr_t RecvFrom( |
229 intptr_t fd, void* buffer, intptr_t num_bytes, RawAddr* addr); | 247 intptr_t fd, void* buffer, intptr_t num_bytes, RawAddr* addr); |
230 static intptr_t CreateConnect(const RawAddr& addr, | 248 static intptr_t CreateConnect(const RawAddr& addr, |
231 const intptr_t port); | 249 const intptr_t port); |
232 static intptr_t CreateBindConnect(const RawAddr& addr, | 250 static intptr_t CreateBindConnect(const RawAddr& addr, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 | 322 |
305 // Start accepting on a newly created listening socket. If it was unable to | 323 // Start accepting on a newly created listening socket. If it was unable to |
306 // start accepting incoming sockets, the fd is invalidated. | 324 // start accepting incoming sockets, the fd is invalidated. |
307 static bool StartAccept(intptr_t fd); | 325 static bool StartAccept(intptr_t fd); |
308 | 326 |
309 private: | 327 private: |
310 DISALLOW_ALLOCATION(); | 328 DISALLOW_ALLOCATION(); |
311 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); | 329 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); |
312 }; | 330 }; |
313 | 331 |
| 332 class ListeningSocketRegistry { |
| 333 private: |
| 334 struct OSSocket { |
| 335 RawAddr address; |
| 336 int port; |
| 337 bool v6_only; |
| 338 bool shared; |
| 339 int ref_count; |
| 340 intptr_t socketfd; |
| 341 |
| 342 // Singly linked lists of OSSocket instances which listen on the same port |
| 343 // but on different addresses. |
| 344 OSSocket *next; |
| 345 |
| 346 OSSocket(RawAddr address, int port, bool v6_only, bool shared, |
| 347 intptr_t socketfd) |
| 348 : address(address), port(port), v6_only(v6_only), shared(shared), |
| 349 ref_count(0), socketfd(socketfd), next(NULL) {} |
| 350 }; |
| 351 |
| 352 public: |
| 353 static bool Initialize(); |
| 354 |
| 355 static ListeningSocketRegistry *Instance(); |
| 356 |
| 357 static void Cleanup(); |
| 358 |
| 359 |
| 360 ListeningSocketRegistry() : mutex_(new Mutex()) {} |
| 361 |
| 362 ~ListeningSocketRegistry() { |
| 363 delete mutex_; |
| 364 mutex_ = NULL; |
| 365 } |
| 366 |
| 367 // This function should be called from a dart runtime call in order to create |
| 368 // a new (potentially shared) socket. |
| 369 Dart_Handle CreateBindListen(Dart_Handle socket_object, |
| 370 RawAddr addr, |
| 371 intptr_t port, |
| 372 intptr_t backlog, |
| 373 bool v6_only, |
| 374 bool shared); |
| 375 |
| 376 // This should be called from the event handler for every kCloseEvent it gets |
| 377 // on listening sockets. |
| 378 // |
| 379 // Returns `true` if the last reference has been dropped and the underlying |
| 380 // socket can be closed. |
| 381 // |
| 382 // The caller is responsible for obtaining the mutex first, before calling |
| 383 // this function. |
| 384 bool CloseSafe(intptr_t socketfd); |
| 385 |
| 386 // Mark an existing socket as sharable if it is not already marked as |
| 387 // sharable. |
| 388 // |
| 389 // NOTE: This is a temporary measure until ServerSocketReference's are |
| 390 // removed. |
| 391 Dart_Handle MarkSocketFdAsSharableHack(intptr_t socketfd); |
| 392 |
| 393 Mutex *mutex() { return mutex_; } |
| 394 |
| 395 private: |
| 396 OSSocket *findOSSocketWithAddress(OSSocket *current, const RawAddr& addr) { |
| 397 while (current != NULL) { |
| 398 if (SocketAddress::AreAddressesEqual(current->address, addr)) { |
| 399 return current; |
| 400 } |
| 401 current = current->next; |
| 402 } |
| 403 return NULL; |
| 404 } |
| 405 |
| 406 std::map<intptr_t, OSSocket*> sockets_by_port_; |
| 407 std::map<intptr_t, OSSocket*> sockets_by_fd_; |
| 408 Mutex *mutex_; |
| 409 |
| 410 typedef std::map<intptr_t, OSSocket*>::iterator SocketsIterator; |
| 411 }; |
| 412 |
| 413 |
314 } // namespace bin | 414 } // namespace bin |
315 } // namespace dart | 415 } // namespace dart |
316 | 416 |
317 #endif // BIN_SOCKET_H_ | 417 #endif // BIN_SOCKET_H_ |
OLD | NEW |