Chromium Code Reviews| 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 |
| 11 | 11 |
| 12 #include "platform/globals.h" | 12 #include "bin/socket_common.h" |
| 13 // Declare the OS-specific types ahead of defining the generic class. | |
| 14 #if defined(TARGET_OS_ANDROID) | |
| 15 #include "bin/socket_android.h" | |
| 16 #elif defined(TARGET_OS_FUCHSIA) | |
| 17 #include "bin/socket_fuchsia.h" | |
| 18 #elif defined(TARGET_OS_LINUX) | |
| 19 #include "bin/socket_linux.h" | |
| 20 #elif defined(TARGET_OS_MACOS) | |
| 21 #include "bin/socket_macos.h" | |
| 22 #elif defined(TARGET_OS_WINDOWS) | |
| 23 #include "bin/socket_win.h" | |
| 24 #else | |
| 25 #error Unknown target os. | |
| 26 #endif | |
| 27 | |
| 28 #include "bin/builtin.h" | 13 #include "bin/builtin.h" |
| 29 #include "bin/dartutils.h" | 14 #include "bin/dartutils.h" |
| 30 #include "bin/thread.h" | 15 #include "bin/thread.h" |
| 31 #include "bin/utils.h" | 16 #include "bin/utils.h" |
| 32 #include "platform/hashmap.h" | 17 #include "platform/hashmap.h" |
| 33 | 18 |
| 34 namespace dart { | 19 namespace dart { |
| 35 namespace bin { | 20 namespace bin { |
| 36 | 21 |
| 37 union RawAddr { | 22 class Socket : public BaseSocket { |
|
zra
2017/03/29 02:37:25
Since BaseSocket is all static, this doesn't do an
bkonyi
2017/03/29 04:09:28
Yes, I know. This was more to show my intentions i
bkonyi
2017/03/29 19:11:40
Removed and added comment as discussed.
| |
| 38 struct sockaddr_in in; | |
| 39 struct sockaddr_in6 in6; | |
| 40 struct sockaddr_storage ss; | |
| 41 struct sockaddr addr; | |
| 42 }; | |
| 43 | |
| 44 class SocketAddress { | |
| 45 public: | |
| 46 enum { | |
| 47 TYPE_ANY = -1, | |
| 48 TYPE_IPV4, | |
| 49 TYPE_IPV6, | |
| 50 }; | |
| 51 | |
| 52 enum { | |
| 53 ADDRESS_LOOPBACK_IP_V4, | |
| 54 ADDRESS_LOOPBACK_IP_V6, | |
| 55 ADDRESS_ANY_IP_V4, | |
| 56 ADDRESS_ANY_IP_V6, | |
| 57 ADDRESS_FIRST = ADDRESS_LOOPBACK_IP_V4, | |
| 58 ADDRESS_LAST = ADDRESS_ANY_IP_V6, | |
| 59 }; | |
| 60 | |
| 61 explicit SocketAddress(struct sockaddr* sa); | |
| 62 | |
| 63 ~SocketAddress() {} | |
| 64 | |
| 65 int GetType() { | |
| 66 if (addr_.ss.ss_family == AF_INET6) { | |
| 67 return TYPE_IPV6; | |
| 68 } | |
| 69 return TYPE_IPV4; | |
| 70 } | |
| 71 | |
| 72 const char* as_string() const { return as_string_; } | |
| 73 const RawAddr& addr() const { return addr_; } | |
| 74 | |
| 75 static intptr_t GetAddrLength(const RawAddr& addr) { | |
| 76 ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6)); | |
| 77 return (addr.ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) | |
| 78 : sizeof(struct sockaddr_in); | |
| 79 } | |
| 80 | |
| 81 static intptr_t GetInAddrLength(const RawAddr& addr) { | |
| 82 ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6)); | |
| 83 return (addr.ss.ss_family == AF_INET6) ? sizeof(struct in6_addr) | |
| 84 : sizeof(struct in_addr); | |
| 85 } | |
| 86 | |
| 87 static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) { | |
| 88 if (a.ss.ss_family == AF_INET) { | |
| 89 if (b.ss.ss_family != AF_INET) { | |
| 90 return false; | |
| 91 } | |
| 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) { | |
| 94 if (b.ss.ss_family != AF_INET6) { | |
| 95 return false; | |
| 96 } | |
| 97 return memcmp(&a.in6.sin6_addr, &b.in6.sin6_addr, | |
| 98 sizeof(a.in6.sin6_addr)) == 0; | |
| 99 } else { | |
| 100 UNREACHABLE(); | |
| 101 return false; | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { | |
| 106 Dart_TypedData_Type data_type; | |
| 107 uint8_t* data = NULL; | |
| 108 intptr_t len; | |
| 109 Dart_Handle result = Dart_TypedDataAcquireData( | |
| 110 obj, &data_type, reinterpret_cast<void**>(&data), &len); | |
| 111 if (Dart_IsError(result)) { | |
| 112 Dart_PropagateError(result); | |
| 113 } | |
| 114 if ((data_type != Dart_TypedData_kUint8) || | |
| 115 ((len != sizeof(in_addr)) && (len != sizeof(in6_addr)))) { | |
| 116 Dart_PropagateError( | |
| 117 Dart_NewApiError("Unexpected type for socket address")); | |
| 118 } | |
| 119 memset(reinterpret_cast<void*>(addr), 0, sizeof(RawAddr)); | |
| 120 if (len == sizeof(in_addr)) { | |
| 121 addr->in.sin_family = AF_INET; | |
| 122 memmove(reinterpret_cast<void*>(&addr->in.sin_addr), data, len); | |
| 123 } else { | |
| 124 ASSERT(len == sizeof(in6_addr)); | |
| 125 addr->in6.sin6_family = AF_INET6; | |
| 126 memmove(reinterpret_cast<void*>(&addr->in6.sin6_addr), data, len); | |
| 127 } | |
| 128 Dart_TypedDataReleaseData(obj); | |
| 129 } | |
| 130 | |
| 131 static int16_t FromType(int type) { | |
| 132 if (type == TYPE_ANY) { | |
| 133 return AF_UNSPEC; | |
| 134 } | |
| 135 if (type == TYPE_IPV4) { | |
| 136 return AF_INET; | |
| 137 } | |
| 138 ASSERT((type == TYPE_IPV6) && "Invalid type"); | |
| 139 return AF_INET6; | |
| 140 } | |
| 141 | |
| 142 static void SetAddrPort(RawAddr* addr, intptr_t port) { | |
| 143 if (addr->ss.ss_family == AF_INET) { | |
| 144 addr->in.sin_port = htons(port); | |
| 145 } else { | |
| 146 addr->in6.sin6_port = htons(port); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 static intptr_t GetAddrPort(const RawAddr& addr) { | |
| 151 if (addr.ss.ss_family == AF_INET) { | |
| 152 return ntohs(addr.in.sin_port); | |
| 153 } else { | |
| 154 return ntohs(addr.in6.sin6_port); | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 static Dart_Handle ToTypedData(const RawAddr& addr) { | |
| 159 int len = GetInAddrLength(addr); | |
| 160 Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len); | |
| 161 if (Dart_IsError(result)) { | |
| 162 Dart_PropagateError(result); | |
| 163 } | |
| 164 Dart_Handle err; | |
| 165 if (addr.addr.sa_family == AF_INET6) { | |
| 166 err = Dart_ListSetAsBytes( | |
| 167 result, 0, reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr), | |
| 168 len); | |
| 169 } else { | |
| 170 err = Dart_ListSetAsBytes( | |
| 171 result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len); | |
| 172 } | |
| 173 if (Dart_IsError(err)) { | |
| 174 Dart_PropagateError(err); | |
| 175 } | |
| 176 return result; | |
| 177 } | |
| 178 | |
| 179 static CObjectUint8Array* ToCObject(const RawAddr& addr) { | |
| 180 int in_addr_len = SocketAddress::GetInAddrLength(addr); | |
| 181 const void* in_addr; | |
| 182 CObjectUint8Array* data = | |
| 183 new CObjectUint8Array(CObject::NewUint8Array(in_addr_len)); | |
| 184 if (addr.addr.sa_family == AF_INET6) { | |
| 185 in_addr = reinterpret_cast<const void*>(&addr.in6.sin6_addr); | |
| 186 } else { | |
| 187 in_addr = reinterpret_cast<const void*>(&addr.in.sin_addr); | |
| 188 } | |
| 189 memmove(data->Buffer(), in_addr, in_addr_len); | |
| 190 return data; | |
| 191 } | |
| 192 | |
| 193 private: | |
| 194 char as_string_[INET6_ADDRSTRLEN]; | |
| 195 RawAddr addr_; | |
| 196 | |
| 197 DISALLOW_COPY_AND_ASSIGN(SocketAddress); | |
| 198 }; | |
| 199 | |
| 200 | |
| 201 class InterfaceSocketAddress { | |
| 202 public: | |
| 203 InterfaceSocketAddress(struct sockaddr* sa, | |
| 204 const char* interface_name, | |
| 205 intptr_t interface_index) | |
| 206 : socket_address_(new SocketAddress(sa)), | |
| 207 interface_name_(interface_name), | |
| 208 interface_index_(interface_index) {} | |
| 209 | |
| 210 ~InterfaceSocketAddress() { delete socket_address_; } | |
| 211 | |
| 212 SocketAddress* socket_address() const { return socket_address_; } | |
| 213 const char* interface_name() const { return interface_name_; } | |
| 214 int interface_index() const { return interface_index_; } | |
| 215 | |
| 216 private: | |
| 217 SocketAddress* socket_address_; | |
| 218 const char* interface_name_; | |
| 219 intptr_t interface_index_; | |
| 220 | |
| 221 DISALLOW_COPY_AND_ASSIGN(InterfaceSocketAddress); | |
| 222 }; | |
| 223 | |
| 224 | |
| 225 template <typename T> | |
| 226 class AddressList { | |
| 227 public: | |
| 228 explicit AddressList(intptr_t count) | |
| 229 : count_(count), addresses_(new T*[count_]) {} | |
| 230 | |
| 231 ~AddressList() { | |
| 232 for (intptr_t i = 0; i < count_; i++) { | |
| 233 delete addresses_[i]; | |
| 234 } | |
| 235 delete[] addresses_; | |
| 236 } | |
| 237 | |
| 238 intptr_t count() const { return count_; } | |
| 239 T* GetAt(intptr_t i) const { return addresses_[i]; } | |
| 240 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; } | |
| 241 | |
| 242 private: | |
| 243 const intptr_t count_; | |
| 244 T** addresses_; | |
| 245 | |
| 246 DISALLOW_COPY_AND_ASSIGN(AddressList); | |
| 247 }; | |
| 248 | |
| 249 | |
| 250 class Socket { | |
| 251 public: | 23 public: |
| 252 enum SocketRequest { | 24 enum SocketRequest { |
| 253 kLookupRequest = 0, | 25 kLookupRequest = 0, |
| 254 kListInterfacesRequest = 1, | 26 kListInterfacesRequest = 1, |
| 255 kReverseLookupRequest = 2, | 27 kReverseLookupRequest = 2, |
| 256 }; | 28 }; |
| 257 | 29 |
| 258 static bool Initialize(); | |
| 259 static intptr_t Available(intptr_t fd); | |
| 260 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes); | |
| 261 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes); | |
| 262 // Send data on a socket. The port to send to is specified in the port | |
| 263 // component of the passed RawAddr structure. The RawAddr structure is only | |
| 264 // used for datagram sockets. | |
| 265 static intptr_t SendTo(intptr_t fd, | |
| 266 const void* buffer, | |
| 267 intptr_t num_bytes, | |
| 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 | 30 // 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. | 31 // specified as the port component of the passed RawAddr structure. |
| 275 static intptr_t CreateConnect(const RawAddr& addr); | 32 static intptr_t CreateConnect(const RawAddr& addr); |
| 276 // Creates a socket which is bound and connected. The port to connect to is | 33 // 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. | 34 // specified as the port component of the passed RawAddr structure. |
| 278 static intptr_t CreateBindConnect(const RawAddr& addr, | 35 static intptr_t CreateBindConnect(const RawAddr& addr, |
| 279 const RawAddr& source_addr); | 36 const RawAddr& source_addr); |
| 280 // Returns true if the given error-number is because the system was not able | |
| 281 // to bind the socket to a specific IP. | |
| 282 static bool IsBindError(intptr_t error_number); | |
| 283 // Creates a datagram socket which is bound. The port to bind | 37 // Creates a datagram socket which is bound. The port to bind |
| 284 // to is specified as the port component of the RawAddr structure. | 38 // to is specified as the port component of the RawAddr structure. |
| 285 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress); | 39 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress); |
| 286 static intptr_t GetPort(intptr_t fd); | |
| 287 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port); | |
| 288 static void GetError(intptr_t fd, OSError* os_error); | |
| 289 static int GetType(intptr_t fd); | |
| 290 static intptr_t GetStdioHandle(intptr_t num); | |
| 291 static void Close(intptr_t fd); | |
| 292 static bool GetNoDelay(intptr_t fd, bool* enabled); | |
| 293 static bool SetNoDelay(intptr_t fd, bool enabled); | |
| 294 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled); | |
| 295 static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled); | |
| 296 static bool GetMulticastHops(intptr_t fd, intptr_t protocol, int* value); | |
| 297 static bool SetMulticastHops(intptr_t fd, intptr_t protocol, int value); | |
| 298 static bool GetBroadcast(intptr_t fd, bool* value); | |
| 299 static bool SetBroadcast(intptr_t fd, bool value); | |
| 300 static bool JoinMulticast(intptr_t fd, | |
| 301 const RawAddr& addr, | |
| 302 const RawAddr& interface, | |
| 303 int interfaceIndex); | |
| 304 static bool LeaveMulticast(intptr_t fd, | |
| 305 const RawAddr& addr, | |
| 306 const RawAddr& interface, | |
| 307 int interfaceIndex); | |
| 308 | |
| 309 // Perform a hostname lookup. Returns a AddressList of SocketAddress's. | |
| 310 static AddressList<SocketAddress>* LookupAddress(const char* host, | |
| 311 int type, | |
| 312 OSError** os_error); | |
| 313 | |
| 314 static bool ReverseLookup(const RawAddr& addr, | |
| 315 char* host, | |
| 316 intptr_t host_len, | |
| 317 OSError** os_error); | |
| 318 | |
| 319 static bool ParseAddress(int type, const char* address, RawAddr* addr); | |
| 320 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len); | |
| 321 | |
| 322 // Whether ListInterfaces is supported. | |
| 323 static bool ListInterfacesSupported(); | |
| 324 | |
| 325 // List interfaces. Returns a AddressList of InterfaceSocketAddress's. | |
| 326 static AddressList<InterfaceSocketAddress>* ListInterfaces( | |
| 327 int type, | |
| 328 OSError** os_error); | |
| 329 | 40 |
| 330 static CObject* LookupRequest(const CObjectArray& request); | 41 static CObject* LookupRequest(const CObjectArray& request); |
| 331 static CObject* ListInterfacesRequest(const CObjectArray& request); | 42 static CObject* ListInterfacesRequest(const CObjectArray& request); |
| 332 static CObject* ReverseLookupRequest(const CObjectArray& request); | 43 static CObject* ReverseLookupRequest(const CObjectArray& request); |
| 333 | 44 |
| 334 static Dart_Port GetServicePort(); | |
| 335 | |
| 336 static void SetSocketIdNativeField(Dart_Handle socket, intptr_t id); | |
| 337 static intptr_t GetSocketIdNativeField(Dart_Handle socket); | |
| 338 | |
| 339 private: | 45 private: |
| 340 DISALLOW_ALLOCATION(); | 46 DISALLOW_ALLOCATION(); |
| 341 DISALLOW_IMPLICIT_CONSTRUCTORS(Socket); | 47 DISALLOW_IMPLICIT_CONSTRUCTORS(Socket); |
| 342 }; | 48 }; |
| 343 | 49 |
| 344 | 50 |
| 345 class ServerSocket { | 51 class ServerSocket { |
| 346 public: | 52 public: |
| 347 static const intptr_t kTemporaryFailure = -2; | 53 static const intptr_t kTemporaryFailure = -2; |
| 348 | 54 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 477 | 183 |
| 478 Mutex* mutex_; | 184 Mutex* mutex_; |
| 479 | 185 |
| 480 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); | 186 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); |
| 481 }; | 187 }; |
| 482 | 188 |
| 483 } // namespace bin | 189 } // namespace bin |
| 484 } // namespace dart | 190 } // namespace dart |
| 485 | 191 |
| 486 #endif // RUNTIME_BIN_SOCKET_H_ | 192 #endif // RUNTIME_BIN_SOCKET_H_ |
| OLD | NEW |