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 | |
10 #include "platform/globals.h" | 8 #include "platform/globals.h" |
11 | 9 |
12 #include "bin/builtin.h" | 10 #include "bin/builtin.h" |
13 #include "bin/dartutils.h" | 11 #include "bin/dartutils.h" |
14 // Declare the OS-specific types ahead of defining the generic class. | 12 // Declare the OS-specific types ahead of defining the generic class. |
15 #if defined(TARGET_OS_ANDROID) | 13 #if defined(TARGET_OS_ANDROID) |
16 #include "bin/socket_android.h" | 14 #include "bin/socket_android.h" |
17 #elif defined(TARGET_OS_LINUX) | 15 #elif defined(TARGET_OS_LINUX) |
18 #include "bin/socket_linux.h" | 16 #include "bin/socket_linux.h" |
19 #elif defined(TARGET_OS_MACOS) | 17 #elif defined(TARGET_OS_MACOS) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 return addr->ss.ss_family == AF_INET6 ? | 69 return addr->ss.ss_family == AF_INET6 ? |
72 sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); | 70 sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); |
73 } | 71 } |
74 | 72 |
75 static intptr_t GetInAddrLength(const RawAddr* addr) { | 73 static intptr_t GetInAddrLength(const RawAddr* addr) { |
76 ASSERT(addr->ss.ss_family == AF_INET || addr->ss.ss_family == AF_INET6); | 74 ASSERT(addr->ss.ss_family == AF_INET || addr->ss.ss_family == AF_INET6); |
77 return addr->ss.ss_family == AF_INET6 ? | 75 return addr->ss.ss_family == AF_INET6 ? |
78 sizeof(struct in6_addr) : sizeof(struct in_addr); | 76 sizeof(struct in6_addr) : sizeof(struct in_addr); |
79 } | 77 } |
80 | 78 |
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 | |
96 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { | 79 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { |
97 Dart_TypedData_Type data_type; | 80 Dart_TypedData_Type data_type; |
98 uint8_t* data = NULL; | 81 uint8_t* data = NULL; |
99 intptr_t len; | 82 intptr_t len; |
100 Dart_Handle result = Dart_TypedDataAcquireData( | 83 Dart_Handle result = Dart_TypedDataAcquireData( |
101 obj, &data_type, reinterpret_cast<void**>(&data), &len); | 84 obj, &data_type, reinterpret_cast<void**>(&data), &len); |
102 if (Dart_IsError(result)) Dart_PropagateError(result); | 85 if (Dart_IsError(result)) Dart_PropagateError(result); |
103 if (data_type != Dart_TypedData_kUint8 || | 86 if (data_type != Dart_TypedData_kUint8 || |
104 (len != sizeof(in_addr) && len != sizeof(in6_addr))) { | 87 (len != sizeof(in_addr) && len != sizeof(in6_addr))) { |
105 Dart_PropagateError( | 88 Dart_PropagateError( |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 | 305 |
323 // Start accepting on a newly created listening socket. If it was unable to | 306 // Start accepting on a newly created listening socket. If it was unable to |
324 // start accepting incoming sockets, the fd is invalidated. | 307 // start accepting incoming sockets, the fd is invalidated. |
325 static bool StartAccept(intptr_t fd); | 308 static bool StartAccept(intptr_t fd); |
326 | 309 |
327 private: | 310 private: |
328 DISALLOW_ALLOCATION(); | 311 DISALLOW_ALLOCATION(); |
329 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); | 312 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); |
330 }; | 313 }; |
331 | 314 |
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 | |
402 } // namespace bin | 315 } // namespace bin |
403 } // namespace dart | 316 } // namespace dart |
404 | 317 |
405 #endif // BIN_SOCKET_H_ | 318 #endif // BIN_SOCKET_H_ |
OLD | NEW |