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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 | 321 |
305 // Start accepting on a newly created listening socket. If it was unable to | 322 // Start accepting on a newly created listening socket. If it was unable to |
306 // start accepting incoming sockets, the fd is invalidated. | 323 // start accepting incoming sockets, the fd is invalidated. |
307 static bool StartAccept(intptr_t fd); | 324 static bool StartAccept(intptr_t fd); |
308 | 325 |
309 private: | 326 private: |
310 DISALLOW_ALLOCATION(); | 327 DISALLOW_ALLOCATION(); |
311 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); | 328 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); |
312 }; | 329 }; |
313 | 330 |
| 331 class ListeningSocketRegistry { |
| 332 private: |
| 333 struct OSSocket { |
| 334 RawAddr address; |
| 335 int port; |
| 336 bool v6_only; |
| 337 bool shared; |
| 338 int ref_count; |
| 339 intptr_t socketfd; |
| 340 |
| 341 // Singly linked lists of OSSocket instances which listen on the same port |
| 342 // but on different addresses. |
| 343 OSSocket *next; |
| 344 |
| 345 OSSocket(RawAddr address, int port, bool v6_only, bool shared, |
| 346 intptr_t socketfd) |
| 347 : address(address), port(port), v6_only(v6_only), shared(shared), |
| 348 ref_count(0), socketfd(socketfd), next(NULL) {} |
| 349 }; |
| 350 |
| 351 public: |
| 352 static void Initialize(); |
| 353 |
| 354 static ListeningSocketRegistry *Instance(); |
| 355 |
| 356 static void Cleanup(); |
| 357 |
| 358 |
| 359 ListeningSocketRegistry() : mutex_(new Mutex()) {} |
| 360 |
| 361 ~ListeningSocketRegistry() { |
| 362 delete mutex_; |
| 363 mutex_ = NULL; |
| 364 } |
| 365 |
| 366 // This function should be called from a dart runtime call in order to create |
| 367 // a new (potentially shared) socket. |
| 368 Dart_Handle CreateBindListen(Dart_Handle socket_object, |
| 369 RawAddr addr, |
| 370 intptr_t port, |
| 371 intptr_t backlog, |
| 372 bool v6_only, |
| 373 bool shared); |
| 374 |
| 375 // This should be called from the event handler for every kCloseEvent it gets |
| 376 // on listening sockets. |
| 377 // |
| 378 // Returns `true` if the last reference has been dropped and the underlying |
| 379 // socket can be closed. |
| 380 // |
| 381 // The caller is responsible for obtaining the mutex first, before calling |
| 382 // this function. |
| 383 bool CloseSafe(intptr_t socketfd); |
| 384 |
| 385 // Mark an existing socket as sharable if it is not already marked as |
| 386 // sharable. |
| 387 // |
| 388 // NOTE: This is a temporary measure until ServerSocketReference's are |
| 389 // removed. |
| 390 Dart_Handle MarkSocketFdAsSharableHack(intptr_t socketfd); |
| 391 |
| 392 Mutex *mutex() { return mutex_; } |
| 393 |
| 394 private: |
| 395 OSSocket *findOSSocketWithAddress(OSSocket *current, const RawAddr& addr) { |
| 396 while (current != NULL) { |
| 397 if (SocketAddress::AreAddressesEqual(current->address, addr)) { |
| 398 return current; |
| 399 } |
| 400 current = current->next; |
| 401 } |
| 402 return NULL; |
| 403 } |
| 404 |
| 405 std::map<intptr_t, OSSocket*> sockets_by_port_; |
| 406 std::map<intptr_t, OSSocket*> sockets_by_fd_; |
| 407 Mutex *mutex_; |
| 408 |
| 409 typedef std::map<intptr_t, OSSocket*>::iterator SocketsIterator; |
| 410 |
| 411 private: |
| 412 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); |
| 413 }; |
| 414 |
| 415 |
314 } // namespace bin | 416 } // namespace bin |
315 } // namespace dart | 417 } // namespace dart |
316 | 418 |
317 #endif // BIN_SOCKET_H_ | 419 #endif // BIN_SOCKET_H_ |
OLD | NEW |