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 RUNTIME_BIN_SOCKET_H_ | 5 #ifndef RUNTIME_BIN_SOCKET_H_ |
6 #define RUNTIME_BIN_SOCKET_H_ | 6 #define RUNTIME_BIN_SOCKET_H_ |
7 | 7 |
8 #if defined(DART_IO_DISABLED) | 8 #if defined(DART_IO_DISABLED) |
9 #error "socket.h can only be included on builds with IO enabled" | 9 #error "socket.h can only be included on builds with IO enabled" |
10 #endif | 10 #endif |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 return TYPE_IPV6; | 67 return TYPE_IPV6; |
68 } | 68 } |
69 return TYPE_IPV4; | 69 return TYPE_IPV4; |
70 } | 70 } |
71 | 71 |
72 const char* as_string() const { return as_string_; } | 72 const char* as_string() const { return as_string_; } |
73 const RawAddr& addr() const { return addr_; } | 73 const RawAddr& addr() const { return addr_; } |
74 | 74 |
75 static intptr_t GetAddrLength(const RawAddr& addr) { | 75 static intptr_t GetAddrLength(const RawAddr& addr) { |
76 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)); |
77 return (addr.ss.ss_family == AF_INET6) ? | 77 return (addr.ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) |
78 sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); | 78 : sizeof(struct sockaddr_in); |
79 } | 79 } |
80 | 80 |
81 static intptr_t GetInAddrLength(const RawAddr& addr) { | 81 static intptr_t GetInAddrLength(const RawAddr& addr) { |
82 ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6)); | 82 ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6)); |
83 return (addr.ss.ss_family == AF_INET6) ? | 83 return (addr.ss.ss_family == AF_INET6) ? sizeof(struct in6_addr) |
84 sizeof(struct in6_addr) : sizeof(struct in_addr); | 84 : sizeof(struct in_addr); |
85 } | 85 } |
86 | 86 |
87 static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) { | 87 static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) { |
88 if (a.ss.ss_family == AF_INET) { | 88 if (a.ss.ss_family == AF_INET) { |
89 if (b.ss.ss_family != AF_INET) { | 89 if (b.ss.ss_family != AF_INET) { |
90 return false; | 90 return false; |
91 } | 91 } |
92 return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0; | 92 return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0; |
93 } else if (a.ss.ss_family == AF_INET6) { | 93 } else if (a.ss.ss_family == AF_INET6) { |
94 if (b.ss.ss_family != AF_INET6) { | 94 if (b.ss.ss_family != AF_INET6) { |
95 return false; | 95 return false; |
96 } | 96 } |
97 return memcmp(&a.in6.sin6_addr, | 97 return memcmp(&a.in6.sin6_addr, &b.in6.sin6_addr, |
98 &b.in6.sin6_addr, | |
99 sizeof(a.in6.sin6_addr)) == 0; | 98 sizeof(a.in6.sin6_addr)) == 0; |
100 } else { | 99 } else { |
101 UNREACHABLE(); | 100 UNREACHABLE(); |
102 return false; | 101 return false; |
103 } | 102 } |
104 } | 103 } |
105 | 104 |
106 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { | 105 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { |
107 Dart_TypedData_Type data_type; | 106 Dart_TypedData_Type data_type; |
108 uint8_t* data = NULL; | 107 uint8_t* data = NULL; |
109 intptr_t len; | 108 intptr_t len; |
110 Dart_Handle result = Dart_TypedDataAcquireData( | 109 Dart_Handle result = Dart_TypedDataAcquireData( |
111 obj, &data_type, reinterpret_cast<void**>(&data), &len); | 110 obj, &data_type, reinterpret_cast<void**>(&data), &len); |
112 if (Dart_IsError(result)) { | 111 if (Dart_IsError(result)) { |
113 Dart_PropagateError(result); | 112 Dart_PropagateError(result); |
114 } | 113 } |
115 if ((data_type != Dart_TypedData_kUint8) || | 114 if ((data_type != Dart_TypedData_kUint8) || |
116 ((len != sizeof(in_addr)) && (len != sizeof(in6_addr)))) { | 115 ((len != sizeof(in_addr)) && (len != sizeof(in6_addr)))) { |
117 Dart_PropagateError( | 116 Dart_PropagateError( |
118 Dart_NewApiError("Unexpected type for socket address")); | 117 Dart_NewApiError("Unexpected type for socket address")); |
119 } | 118 } |
120 memset(reinterpret_cast<void*>(addr), 0, sizeof(RawAddr)); | 119 memset(reinterpret_cast<void*>(addr), 0, sizeof(RawAddr)); |
121 if (len == sizeof(in_addr)) { | 120 if (len == sizeof(in_addr)) { |
122 addr->in.sin_family = AF_INET; | 121 addr->in.sin_family = AF_INET; |
123 memmove(reinterpret_cast<void *>(&addr->in.sin_addr), data, len); | 122 memmove(reinterpret_cast<void*>(&addr->in.sin_addr), data, len); |
124 } else { | 123 } else { |
125 ASSERT(len == sizeof(in6_addr)); | 124 ASSERT(len == sizeof(in6_addr)); |
126 addr->in6.sin6_family = AF_INET6; | 125 addr->in6.sin6_family = AF_INET6; |
127 memmove(reinterpret_cast<void*>(&addr->in6.sin6_addr), data, len); | 126 memmove(reinterpret_cast<void*>(&addr->in6.sin6_addr), data, len); |
128 } | 127 } |
129 Dart_TypedDataReleaseData(obj); | 128 Dart_TypedDataReleaseData(obj); |
130 } | 129 } |
131 | 130 |
132 static int16_t FromType(int type) { | 131 static int16_t FromType(int type) { |
133 if (type == TYPE_ANY) { | 132 if (type == TYPE_ANY) { |
(...skipping 24 matching lines...) Expand all Loading... |
158 | 157 |
159 static Dart_Handle ToTypedData(const RawAddr& addr) { | 158 static Dart_Handle ToTypedData(const RawAddr& addr) { |
160 int len = GetInAddrLength(addr); | 159 int len = GetInAddrLength(addr); |
161 Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len); | 160 Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len); |
162 if (Dart_IsError(result)) { | 161 if (Dart_IsError(result)) { |
163 Dart_PropagateError(result); | 162 Dart_PropagateError(result); |
164 } | 163 } |
165 Dart_Handle err; | 164 Dart_Handle err; |
166 if (addr.addr.sa_family == AF_INET6) { | 165 if (addr.addr.sa_family == AF_INET6) { |
167 err = Dart_ListSetAsBytes( | 166 err = Dart_ListSetAsBytes( |
168 result, 0, | 167 result, 0, reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr), |
169 reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr), len); | 168 len); |
170 } else { | 169 } else { |
171 err = Dart_ListSetAsBytes( | 170 err = Dart_ListSetAsBytes( |
172 result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len); | 171 result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len); |
173 } | 172 } |
174 if (Dart_IsError(err)) { | 173 if (Dart_IsError(err)) { |
175 Dart_PropagateError(err); | 174 Dart_PropagateError(err); |
176 } | 175 } |
177 return result; | 176 return result; |
178 } | 177 } |
179 | 178 |
(...skipping 21 matching lines...) Expand all Loading... |
201 | 200 |
202 class InterfaceSocketAddress { | 201 class InterfaceSocketAddress { |
203 public: | 202 public: |
204 InterfaceSocketAddress(struct sockaddr* sa, | 203 InterfaceSocketAddress(struct sockaddr* sa, |
205 const char* interface_name, | 204 const char* interface_name, |
206 intptr_t interface_index) | 205 intptr_t interface_index) |
207 : socket_address_(new SocketAddress(sa)), | 206 : socket_address_(new SocketAddress(sa)), |
208 interface_name_(interface_name), | 207 interface_name_(interface_name), |
209 interface_index_(interface_index) {} | 208 interface_index_(interface_index) {} |
210 | 209 |
211 ~InterfaceSocketAddress() { | 210 ~InterfaceSocketAddress() { delete socket_address_; } |
212 delete socket_address_; | |
213 } | |
214 | 211 |
215 SocketAddress* socket_address() const { return socket_address_; } | 212 SocketAddress* socket_address() const { return socket_address_; } |
216 const char* interface_name() const { return interface_name_; } | 213 const char* interface_name() const { return interface_name_; } |
217 int interface_index() const { return interface_index_; } | 214 int interface_index() const { return interface_index_; } |
218 | 215 |
219 private: | 216 private: |
220 SocketAddress* socket_address_; | 217 SocketAddress* socket_address_; |
221 const char* interface_name_; | 218 const char* interface_name_; |
222 intptr_t interface_index_; | 219 intptr_t interface_index_; |
223 | 220 |
224 DISALLOW_COPY_AND_ASSIGN(InterfaceSocketAddress); | 221 DISALLOW_COPY_AND_ASSIGN(InterfaceSocketAddress); |
225 }; | 222 }; |
226 | 223 |
227 | 224 |
228 template<typename T> | 225 template <typename T> |
229 class AddressList { | 226 class AddressList { |
230 public: | 227 public: |
231 explicit AddressList(intptr_t count) | 228 explicit AddressList(intptr_t count) |
232 : count_(count), | 229 : count_(count), addresses_(new T*[count_]) {} |
233 addresses_(new T*[count_]) {} | |
234 | 230 |
235 ~AddressList() { | 231 ~AddressList() { |
236 for (intptr_t i = 0; i < count_; i++) { | 232 for (intptr_t i = 0; i < count_; i++) { |
237 delete addresses_[i]; | 233 delete addresses_[i]; |
238 } | 234 } |
239 delete[] addresses_; | 235 delete[] addresses_; |
240 } | 236 } |
241 | 237 |
242 intptr_t count() const { return count_; } | 238 intptr_t count() const { return count_; } |
243 T* GetAt(intptr_t i) const { return addresses_[i]; } | 239 T* GetAt(intptr_t i) const { return addresses_[i]; } |
(...skipping 15 matching lines...) Expand all Loading... |
259 kReverseLookupRequest = 2, | 255 kReverseLookupRequest = 2, |
260 }; | 256 }; |
261 | 257 |
262 static bool Initialize(); | 258 static bool Initialize(); |
263 static intptr_t Available(intptr_t fd); | 259 static intptr_t Available(intptr_t fd); |
264 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes); | 260 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes); |
265 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes); | 261 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes); |
266 // Send data on a socket. The port to send to is specified in the port | 262 // Send data on a socket. The port to send to is specified in the port |
267 // component of the passed RawAddr structure. The RawAddr structure is only | 263 // component of the passed RawAddr structure. The RawAddr structure is only |
268 // used for datagram sockets. | 264 // used for datagram sockets. |
269 static intptr_t SendTo( | 265 static intptr_t SendTo(intptr_t fd, |
270 intptr_t fd, const void* buffer, intptr_t num_bytes, const RawAddr& addr); | 266 const void* buffer, |
271 static intptr_t RecvFrom( | 267 intptr_t num_bytes, |
272 intptr_t fd, void* buffer, intptr_t num_bytes, RawAddr* addr); | 268 const RawAddr& addr); |
| 269 static intptr_t RecvFrom(intptr_t fd, |
| 270 void* buffer, |
| 271 intptr_t num_bytes, |
| 272 RawAddr* addr); |
273 // Creates a socket which is bound and connected. The port to connect to is | 273 // Creates a socket which is bound and connected. The port to connect to is |
274 // specified as the port component of the passed RawAddr structure. | 274 // specified as the port component of the passed RawAddr structure. |
275 static intptr_t CreateConnect(const RawAddr& addr); | 275 static intptr_t CreateConnect(const RawAddr& addr); |
276 // Creates a socket which is bound and connected. The port to connect to is | 276 // Creates a socket which is bound and connected. The port to connect to is |
277 // specified as the port component of the passed RawAddr structure. | 277 // specified as the port component of the passed RawAddr structure. |
278 static intptr_t CreateBindConnect(const RawAddr& addr, | 278 static intptr_t CreateBindConnect(const RawAddr& addr, |
279 const RawAddr& source_addr); | 279 const RawAddr& source_addr); |
280 // Returns true if the given error-number is because the system was not able | 280 // Returns true if the given error-number is because the system was not able |
281 // to bind the socket to a specific IP. | 281 // to bind the socket to a specific IP. |
282 static bool IsBindError(intptr_t error_number); | 282 static bool IsBindError(intptr_t error_number); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 static bool StartAccept(intptr_t fd); | 365 static bool StartAccept(intptr_t fd); |
366 | 366 |
367 private: | 367 private: |
368 DISALLOW_ALLOCATION(); | 368 DISALLOW_ALLOCATION(); |
369 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); | 369 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); |
370 }; | 370 }; |
371 | 371 |
372 | 372 |
373 class ListeningSocketRegistry { | 373 class ListeningSocketRegistry { |
374 public: | 374 public: |
375 ListeningSocketRegistry() : | 375 ListeningSocketRegistry() |
376 sockets_by_port_(SameIntptrValue, kInitialSocketsCount), | 376 : sockets_by_port_(SameIntptrValue, kInitialSocketsCount), |
377 sockets_by_fd_(SameIntptrValue, kInitialSocketsCount), | 377 sockets_by_fd_(SameIntptrValue, kInitialSocketsCount), |
378 mutex_(new Mutex()) {} | 378 mutex_(new Mutex()) {} |
379 | 379 |
380 ~ListeningSocketRegistry() { | 380 ~ListeningSocketRegistry() { |
381 CloseAllSafe(); | 381 CloseAllSafe(); |
382 delete mutex_; | 382 delete mutex_; |
383 mutex_ = NULL; | 383 mutex_ = NULL; |
384 } | 384 } |
385 | 385 |
386 static void Initialize(); | 386 static void Initialize(); |
387 | 387 |
388 static ListeningSocketRegistry *Instance(); | 388 static ListeningSocketRegistry* Instance(); |
389 | 389 |
390 static void Cleanup(); | 390 static void Cleanup(); |
391 | 391 |
392 // This function should be called from a dart runtime call in order to create | 392 // This function should be called from a dart runtime call in order to create |
393 // a new (potentially shared) socket. | 393 // a new (potentially shared) socket. |
394 Dart_Handle CreateBindListen(Dart_Handle socket_object, | 394 Dart_Handle CreateBindListen(Dart_Handle socket_object, |
395 RawAddr addr, | 395 RawAddr addr, |
396 intptr_t backlog, | 396 intptr_t backlog, |
397 bool v6_only, | 397 bool v6_only, |
398 bool shared); | 398 bool shared); |
399 | 399 |
400 // This should be called from the event handler for every kCloseEvent it gets | 400 // This should be called from the event handler for every kCloseEvent it gets |
401 // on listening sockets. | 401 // on listening sockets. |
402 // | 402 // |
403 // Returns `true` if the last reference has been dropped and the underlying | 403 // Returns `true` if the last reference has been dropped and the underlying |
404 // socket can be closed. | 404 // socket can be closed. |
405 // | 405 // |
406 // The caller is responsible for obtaining the mutex first, before calling | 406 // The caller is responsible for obtaining the mutex first, before calling |
407 // this function. | 407 // this function. |
408 bool CloseSafe(intptr_t socketfd); | 408 bool CloseSafe(intptr_t socketfd); |
409 | 409 |
410 Mutex *mutex() { return mutex_; } | 410 Mutex* mutex() { return mutex_; } |
411 | 411 |
412 private: | 412 private: |
413 struct OSSocket { | 413 struct OSSocket { |
414 RawAddr address; | 414 RawAddr address; |
415 int port; | 415 int port; |
416 bool v6_only; | 416 bool v6_only; |
417 bool shared; | 417 bool shared; |
418 int ref_count; | 418 int ref_count; |
419 intptr_t socketfd; | 419 intptr_t socketfd; |
420 | 420 |
421 // Singly linked lists of OSSocket instances which listen on the same port | 421 // Singly linked lists of OSSocket instances which listen on the same port |
422 // but on different addresses. | 422 // but on different addresses. |
423 OSSocket *next; | 423 OSSocket* next; |
424 | 424 |
425 OSSocket(RawAddr address, int port, bool v6_only, bool shared, | 425 OSSocket(RawAddr address, |
| 426 int port, |
| 427 bool v6_only, |
| 428 bool shared, |
426 intptr_t socketfd) | 429 intptr_t socketfd) |
427 : address(address), port(port), v6_only(v6_only), shared(shared), | 430 : address(address), |
428 ref_count(0), socketfd(socketfd), next(NULL) {} | 431 port(port), |
| 432 v6_only(v6_only), |
| 433 shared(shared), |
| 434 ref_count(0), |
| 435 socketfd(socketfd), |
| 436 next(NULL) {} |
429 }; | 437 }; |
430 | 438 |
431 static const intptr_t kInitialSocketsCount = 8; | 439 static const intptr_t kInitialSocketsCount = 8; |
432 | 440 |
433 OSSocket *findOSSocketWithAddress(OSSocket *current, const RawAddr& addr) { | 441 OSSocket* findOSSocketWithAddress(OSSocket* current, const RawAddr& addr) { |
434 while (current != NULL) { | 442 while (current != NULL) { |
435 if (SocketAddress::AreAddressesEqual(current->address, addr)) { | 443 if (SocketAddress::AreAddressesEqual(current->address, addr)) { |
436 return current; | 444 return current; |
437 } | 445 } |
438 current = current->next; | 446 current = current->next; |
439 } | 447 } |
440 return NULL; | 448 return NULL; |
441 } | 449 } |
442 | 450 |
443 static bool SameIntptrValue(void* key1, void* key2) { | 451 static bool SameIntptrValue(void* key1, void* key2) { |
(...skipping 16 matching lines...) Expand all Loading... |
460 OSSocket* LookupByFd(intptr_t fd); | 468 OSSocket* LookupByFd(intptr_t fd); |
461 void InsertByFd(intptr_t fd, OSSocket* socket); | 469 void InsertByFd(intptr_t fd, OSSocket* socket); |
462 void RemoveByFd(intptr_t fd); | 470 void RemoveByFd(intptr_t fd); |
463 | 471 |
464 bool CloseOneSafe(OSSocket* os_socket); | 472 bool CloseOneSafe(OSSocket* os_socket); |
465 void CloseAllSafe(); | 473 void CloseAllSafe(); |
466 | 474 |
467 HashMap sockets_by_port_; | 475 HashMap sockets_by_port_; |
468 HashMap sockets_by_fd_; | 476 HashMap sockets_by_fd_; |
469 | 477 |
470 Mutex *mutex_; | 478 Mutex* mutex_; |
471 | 479 |
472 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); | 480 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); |
473 }; | 481 }; |
474 | 482 |
475 } // namespace bin | 483 } // namespace bin |
476 } // namespace dart | 484 } // namespace dart |
477 | 485 |
478 #endif // RUNTIME_BIN_SOCKET_H_ | 486 #endif // RUNTIME_BIN_SOCKET_H_ |
OLD | NEW |