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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 | 322 |
306 // 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 |
307 // start accepting incoming sockets, the fd is invalidated. | 324 // start accepting incoming sockets, the fd is invalidated. |
308 static bool StartAccept(intptr_t fd); | 325 static bool StartAccept(intptr_t fd); |
309 | 326 |
310 private: | 327 private: |
311 DISALLOW_ALLOCATION(); | 328 DISALLOW_ALLOCATION(); |
312 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); | 329 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); |
313 }; | 330 }; |
314 | 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 int 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, int 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 ListeningSocketRegistry() : mutex_(new Mutex()) {} |
| 353 |
| 354 // This function should be called from a dart runtime call in order to create |
| 355 // a new (potentially shared) socket. |
| 356 Dart_Handle CreateBindListen(Dart_Handle socket_object, |
| 357 RawAddr addr, |
| 358 intptr_t port, |
| 359 intptr_t backlog, |
| 360 bool v6_only, |
| 361 bool shared); |
| 362 |
| 363 // This should be called from the event handler for every kCloseEvent it gets |
| 364 // on listening sockets. |
| 365 // |
| 366 // Returns `true` if the last reference has been dropped and the underlying |
| 367 // socket can be closed. |
| 368 // |
| 369 // The caller is responsible for obtaining the mutex first, before calling |
| 370 // this function. |
| 371 bool CloseSafe(int socketfd); |
| 372 |
| 373 // Mark an existing socket as sharable if it is not already marked as |
| 374 // sharable. |
| 375 // |
| 376 // NOTE: This is a temporary measure until ServerSocketReference's are |
| 377 // removed. |
| 378 Dart_Handle MarkSocketFdAsSharableHack(int socketfd); |
| 379 |
| 380 Mutex *mutex() { return mutex_; } |
| 381 |
| 382 private: |
| 383 OSSocket *findOSSocketWithAddress(OSSocket *current, const RawAddr& addr) { |
| 384 while (current != NULL) { |
| 385 if (SocketAddress::AreAddressesEqual(current->address, addr)) { |
| 386 return current; |
| 387 } |
| 388 current = current->next; |
| 389 } |
| 390 return NULL; |
| 391 } |
| 392 |
| 393 std::map<intptr_t, OSSocket*> sockets_by_port_; |
| 394 std::map<intptr_t, OSSocket*> sockets_by_fd_; |
| 395 Mutex *mutex_; |
| 396 |
| 397 typedef std::map<intptr_t, OSSocket*>::iterator SocketsIterator; |
| 398 }; |
| 399 |
| 400 extern ListeningSocketRegistry globalTcpListeningSocketRegistry; |
| 401 |
315 } // namespace bin | 402 } // namespace bin |
316 } // namespace dart | 403 } // namespace dart |
317 | 404 |
318 #endif // BIN_SOCKET_H_ | 405 #endif // BIN_SOCKET_H_ |
OLD | NEW |