Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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_BASE_H_ |
| 6 #define RUNTIME_BIN_SOCKET_H_ | 6 #define RUNTIME_BIN_SOCKET_BASE_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_base.h can only be included on builds with IO enabled" |
| 10 #endif | 10 #endif |
| 11 | 11 |
| 12 #include "platform/globals.h" | 12 #include "platform/globals.h" |
| 13 // Declare the OS-specific types ahead of defining the generic class. | 13 // Declare the OS-specific types ahead of defining the generic class. |
| 14 #if defined(HOST_OS_ANDROID) | 14 #if defined(TARGET_OS_ANDROID) |
|
zra
2017/04/03 03:40:23
I think these should probably still be HOST_OS_*
rmacnak
2017/04/03 16:03:55
Right, HOST_OS. Only the AOT compiler should be us
bkonyi
2017/04/03 16:09:57
Good to know! I don't know why/how these were chan
| |
| 15 #include "bin/socket_android.h" | 15 #include "bin/socket_base_android.h" |
| 16 #elif defined(HOST_OS_FUCHSIA) | 16 #elif defined(TARGET_OS_FUCHSIA) |
| 17 #include "bin/socket_fuchsia.h" | 17 #include "bin/socket_base_fuchsia.h" |
| 18 #elif defined(HOST_OS_LINUX) | 18 #elif defined(TARGET_OS_LINUX) |
| 19 #include "bin/socket_linux.h" | 19 #include "bin/socket_base_linux.h" |
| 20 #elif defined(HOST_OS_MACOS) | 20 #elif defined(TARGET_OS_MACOS) |
| 21 #include "bin/socket_macos.h" | 21 #include "bin/socket_base_macos.h" |
| 22 #elif defined(HOST_OS_WINDOWS) | 22 #elif defined(TARGET_OS_WINDOWS) |
| 23 #include "bin/socket_win.h" | 23 #include "bin/socket_base_win.h" |
| 24 #else | 24 #else |
| 25 #error Unknown target os. | 25 #error Unknown target os. |
| 26 #endif | 26 #endif |
| 27 | 27 |
| 28 #include "bin/builtin.h" | 28 #include "bin/builtin.h" |
| 29 #include "bin/dartutils.h" | 29 #include "bin/dartutils.h" |
| 30 #include "bin/reference_counting.h" | |
| 31 #include "bin/thread.h" | 30 #include "bin/thread.h" |
| 32 #include "bin/utils.h" | 31 #include "bin/utils.h" |
| 32 #include "platform/allocation.h" | |
| 33 #include "platform/hashmap.h" | 33 #include "platform/hashmap.h" |
| 34 | 34 |
| 35 namespace dart { | 35 namespace dart { |
| 36 namespace bin { | 36 namespace bin { |
| 37 | 37 |
| 38 union RawAddr { | 38 union RawAddr { |
| 39 struct sockaddr_in in; | 39 struct sockaddr_in in; |
| 40 struct sockaddr_in6 in6; | 40 struct sockaddr_in6 in6; |
| 41 struct sockaddr_storage ss; | 41 struct sockaddr_storage ss; |
| 42 struct sockaddr addr; | 42 struct sockaddr addr; |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 T* GetAt(intptr_t i) const { return addresses_[i]; } | 240 T* GetAt(intptr_t i) const { return addresses_[i]; } |
| 241 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; } | 241 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; } |
| 242 | 242 |
| 243 private: | 243 private: |
| 244 const intptr_t count_; | 244 const intptr_t count_; |
| 245 T** addresses_; | 245 T** addresses_; |
| 246 | 246 |
| 247 DISALLOW_COPY_AND_ASSIGN(AddressList); | 247 DISALLOW_COPY_AND_ASSIGN(AddressList); |
| 248 }; | 248 }; |
| 249 | 249 |
| 250 | 250 class SocketBase : public AllStatic { |
| 251 // We write Sockets into the native field of the _NativeSocket object | |
| 252 // on the Dart side. They are allocated in SetSocketIdNativeField(), and are | |
| 253 // deallocated either from the finalizer attached to _NativeSockets there, or | |
| 254 // from the eventhandler, whichever drops the last reference. | |
| 255 class Socket : public ReferenceCounted<Socket> { | |
| 256 public: | 251 public: |
| 257 enum SocketRequest { | 252 enum SocketRequest { |
| 258 kLookupRequest = 0, | 253 kLookupRequest = 0, |
| 259 kListInterfacesRequest = 1, | 254 kListInterfacesRequest = 1, |
| 260 kReverseLookupRequest = 2, | 255 kReverseLookupRequest = 2, |
| 261 }; | 256 }; |
| 262 | 257 |
| 263 explicit Socket(intptr_t fd); | |
| 264 | |
| 265 intptr_t fd() const { return fd_; } | |
| 266 void SetClosedFd(); | |
| 267 | |
| 268 Dart_Port port() const { return port_; } | |
| 269 void set_port(Dart_Port port) { port_ = port; } | |
| 270 | |
| 271 // TODO(dart:io): Convert these to instance methods where possible. | 258 // TODO(dart:io): Convert these to instance methods where possible. |
| 272 static bool Initialize(); | |
| 273 static intptr_t Available(intptr_t fd); | 259 static intptr_t Available(intptr_t fd); |
| 274 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); |
| 275 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); |
| 276 // 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 |
| 277 // component of the passed RawAddr structure. The RawAddr structure is only | 263 // component of the passed RawAddr structure. The RawAddr structure is only |
| 278 // used for datagram sockets. | 264 // used for datagram sockets. |
| 279 static intptr_t SendTo(intptr_t fd, | 265 static intptr_t SendTo(intptr_t fd, |
| 280 const void* buffer, | 266 const void* buffer, |
| 281 intptr_t num_bytes, | 267 intptr_t num_bytes, |
| 282 const RawAddr& addr); | 268 const RawAddr& addr); |
| 283 static intptr_t RecvFrom(intptr_t fd, | 269 static intptr_t RecvFrom(intptr_t fd, |
| 284 void* buffer, | 270 void* buffer, |
| 285 intptr_t num_bytes, | 271 intptr_t num_bytes, |
| 286 RawAddr* addr); | 272 RawAddr* addr); |
| 287 // Creates a socket which is bound and connected. The port to connect to is | |
| 288 // specified as the port component of the passed RawAddr structure. | |
| 289 static intptr_t CreateConnect(const RawAddr& addr); | |
| 290 // Creates a socket which is bound and connected. The port to connect to is | |
| 291 // specified as the port component of the passed RawAddr structure. | |
| 292 static intptr_t CreateBindConnect(const RawAddr& addr, | |
| 293 const RawAddr& source_addr); | |
| 294 // Returns true if the given error-number is because the system was not able | 273 // Returns true if the given error-number is because the system was not able |
| 295 // to bind the socket to a specific IP. | 274 // to bind the socket to a specific IP. |
| 296 static bool IsBindError(intptr_t error_number); | 275 static bool IsBindError(intptr_t error_number); |
| 297 // Creates a datagram socket which is bound. The port to bind | |
| 298 // to is specified as the port component of the RawAddr structure. | |
| 299 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress); | |
| 300 static intptr_t GetPort(intptr_t fd); | 276 static intptr_t GetPort(intptr_t fd); |
| 301 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port); | 277 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port); |
| 302 static void GetError(intptr_t fd, OSError* os_error); | 278 static void GetError(intptr_t fd, OSError* os_error); |
| 303 static int GetType(intptr_t fd); | 279 static int GetType(intptr_t fd); |
| 304 static intptr_t GetStdioHandle(intptr_t num); | 280 static intptr_t GetStdioHandle(intptr_t num); |
| 305 static void Close(intptr_t fd); | 281 static void Close(intptr_t fd); |
| 306 static bool GetNoDelay(intptr_t fd, bool* enabled); | 282 static bool GetNoDelay(intptr_t fd, bool* enabled); |
| 307 static bool SetNoDelay(intptr_t fd, bool enabled); | 283 static bool SetNoDelay(intptr_t fd, bool enabled); |
| 308 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled); | 284 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled); |
| 309 static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled); | 285 static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 334 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len); | 310 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len); |
| 335 | 311 |
| 336 // Whether ListInterfaces is supported. | 312 // Whether ListInterfaces is supported. |
| 337 static bool ListInterfacesSupported(); | 313 static bool ListInterfacesSupported(); |
| 338 | 314 |
| 339 // List interfaces. Returns a AddressList of InterfaceSocketAddress's. | 315 // List interfaces. Returns a AddressList of InterfaceSocketAddress's. |
| 340 static AddressList<InterfaceSocketAddress>* ListInterfaces( | 316 static AddressList<InterfaceSocketAddress>* ListInterfaces( |
| 341 int type, | 317 int type, |
| 342 OSError** os_error); | 318 OSError** os_error); |
| 343 | 319 |
| 344 static CObject* LookupRequest(const CObjectArray& request); | |
| 345 static CObject* ListInterfacesRequest(const CObjectArray& request); | |
| 346 static CObject* ReverseLookupRequest(const CObjectArray& request); | |
| 347 | |
| 348 static Dart_Port GetServicePort(); | |
| 349 | |
| 350 static void SetSocketIdNativeField(Dart_Handle handle, | |
| 351 intptr_t id, | |
| 352 bool listening); | |
| 353 static void ReuseSocketIdNativeField(Dart_Handle handle, | |
| 354 Socket* socket, | |
| 355 bool listening); | |
| 356 static Socket* GetSocketIdNativeField(Dart_Handle socket); | |
| 357 | |
| 358 private: | |
| 359 ~Socket() { ASSERT(fd_ == kClosedFd); } | |
| 360 | |
| 361 static const int kClosedFd = -1; | |
| 362 | |
| 363 intptr_t fd_; | |
| 364 Dart_Port port_; | |
| 365 | |
| 366 friend class ReferenceCounted<Socket>; | |
| 367 DISALLOW_COPY_AND_ASSIGN(Socket); | |
| 368 }; | |
| 369 | |
| 370 | |
| 371 class ServerSocket { | |
| 372 public: | |
| 373 static const intptr_t kTemporaryFailure = -2; | |
| 374 | |
| 375 static intptr_t Accept(intptr_t fd); | |
| 376 | |
| 377 // Creates a socket which is bound and listens. The port to listen on is | |
| 378 // specified in the port component of the passed RawAddr structure. | |
| 379 // | |
| 380 // Returns a positive integer if the call is successful. In case of failure | |
| 381 // it returns: | |
| 382 // | |
| 383 // -1: system error (errno set) | |
| 384 // -5: invalid bindAddress | |
| 385 static intptr_t CreateBindListen(const RawAddr& addr, | |
| 386 intptr_t backlog, | |
| 387 bool v6_only = false); | |
| 388 | |
| 389 // Start accepting on a newly created listening socket. If it was unable to | |
| 390 // start accepting incoming sockets, the fd is invalidated. | |
| 391 static bool StartAccept(intptr_t fd); | |
| 392 | |
| 393 private: | 320 private: |
| 394 DISALLOW_ALLOCATION(); | 321 DISALLOW_ALLOCATION(); |
| 395 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); | 322 DISALLOW_IMPLICIT_CONSTRUCTORS(SocketBase); |
| 396 }; | |
| 397 | |
| 398 | |
| 399 class ListeningSocketRegistry { | |
| 400 public: | |
| 401 ListeningSocketRegistry() | |
| 402 : sockets_by_port_(SameIntptrValue, kInitialSocketsCount), | |
| 403 sockets_by_fd_(SameIntptrValue, kInitialSocketsCount), | |
| 404 mutex_(new Mutex()) {} | |
| 405 | |
| 406 ~ListeningSocketRegistry() { | |
| 407 CloseAllSafe(); | |
| 408 delete mutex_; | |
| 409 mutex_ = NULL; | |
| 410 } | |
| 411 | |
| 412 static void Initialize(); | |
| 413 | |
| 414 static ListeningSocketRegistry* Instance(); | |
| 415 | |
| 416 static void Cleanup(); | |
| 417 | |
| 418 // This function should be called from a dart runtime call in order to create | |
| 419 // a new (potentially shared) socket. | |
| 420 Dart_Handle CreateBindListen(Dart_Handle socket_object, | |
| 421 RawAddr addr, | |
| 422 intptr_t backlog, | |
| 423 bool v6_only, | |
| 424 bool shared); | |
| 425 | |
| 426 // This should be called from the event handler for every kCloseEvent it gets | |
| 427 // on listening sockets. | |
| 428 // | |
| 429 // Returns `true` if the last reference has been dropped and the underlying | |
| 430 // socket can be closed. | |
| 431 // | |
| 432 // The caller is responsible for obtaining the mutex first, before calling | |
| 433 // this function. | |
| 434 bool CloseSafe(Socket* socketfd); | |
| 435 | |
| 436 Mutex* mutex() { return mutex_; } | |
| 437 | |
| 438 private: | |
| 439 struct OSSocket { | |
| 440 RawAddr address; | |
| 441 int port; | |
| 442 bool v6_only; | |
| 443 bool shared; | |
| 444 int ref_count; | |
| 445 Socket* socketfd; | |
| 446 | |
| 447 // Singly linked lists of OSSocket instances which listen on the same port | |
| 448 // but on different addresses. | |
| 449 OSSocket* next; | |
| 450 | |
| 451 OSSocket(RawAddr address, | |
| 452 int port, | |
| 453 bool v6_only, | |
| 454 bool shared, | |
| 455 Socket* socketfd) | |
| 456 : address(address), | |
| 457 port(port), | |
| 458 v6_only(v6_only), | |
| 459 shared(shared), | |
| 460 ref_count(0), | |
| 461 socketfd(socketfd), | |
| 462 next(NULL) {} | |
| 463 }; | |
| 464 | |
| 465 static const intptr_t kInitialSocketsCount = 8; | |
| 466 | |
| 467 OSSocket* FindOSSocketWithAddress(OSSocket* current, const RawAddr& addr) { | |
| 468 while (current != NULL) { | |
| 469 if (SocketAddress::AreAddressesEqual(current->address, addr)) { | |
| 470 return current; | |
| 471 } | |
| 472 current = current->next; | |
| 473 } | |
| 474 return NULL; | |
| 475 } | |
| 476 | |
| 477 static bool SameIntptrValue(void* key1, void* key2) { | |
| 478 return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2); | |
| 479 } | |
| 480 | |
| 481 static uint32_t GetHashmapHashFromIntptr(intptr_t i) { | |
| 482 return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF); | |
| 483 } | |
| 484 | |
| 485 | |
| 486 static void* GetHashmapKeyFromIntptr(intptr_t i) { | |
| 487 return reinterpret_cast<void*>(i + 1); | |
| 488 } | |
| 489 | |
| 490 OSSocket* LookupByPort(intptr_t port); | |
| 491 void InsertByPort(intptr_t port, OSSocket* socket); | |
| 492 void RemoveByPort(intptr_t port); | |
| 493 | |
| 494 OSSocket* LookupByFd(Socket* fd); | |
| 495 void InsertByFd(Socket* fd, OSSocket* socket); | |
| 496 void RemoveByFd(Socket* fd); | |
| 497 | |
| 498 bool CloseOneSafe(OSSocket* os_socket, bool update_hash_maps); | |
| 499 void CloseAllSafe(); | |
| 500 | |
| 501 HashMap sockets_by_port_; | |
| 502 HashMap sockets_by_fd_; | |
| 503 | |
| 504 Mutex* mutex_; | |
| 505 | |
| 506 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); | |
| 507 }; | 323 }; |
| 508 | 324 |
| 509 } // namespace bin | 325 } // namespace bin |
| 510 } // namespace dart | 326 } // namespace dart |
| 511 | 327 |
| 512 #endif // RUNTIME_BIN_SOCKET_H_ | 328 #endif // RUNTIME_BIN_SOCKET_BASE_H_ |
| OLD | NEW |