Flutter Engine
The Flutter Engine
socket.h
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_BIN_SOCKET_H_
6#define RUNTIME_BIN_SOCKET_H_
7
8#include "bin/builtin.h"
9#include "bin/dartutils.h"
10#include "bin/file.h"
12#include "bin/socket_base.h"
13#include "bin/thread.h"
14#include "bin/utils.h"
15#include "platform/hashmap.h"
16
17namespace dart {
18namespace bin {
19
20// TODO(bkonyi): Socket should also inherit from SocketBase once it is
21// refactored to use instance methods when possible.
22
23// We write Sockets into the native field of the _NativeSocket object
24// on the Dart side. They are allocated in SetSocketIdNativeField(), and are
25// deallocated either from the finalizer attached to _NativeSockets there, or
26// from the eventhandler, whichever drops the last reference.
27class Socket : public ReferenceCounted<Socket> {
28 public:
33 };
34
40 };
41
42 // Keep in sync with constants in _NativeSocket in socket_patch.dart.
48 };
49
50 explicit Socket(intptr_t fd);
51
52 intptr_t fd() const { return fd_; }
53
54 // Close fd and may need to decrement the count of handle by calling
55 // release().
56 void CloseFd();
57 // Set fd_ to closed. On fuchsia and win, shared socket should not
58 // release handle but only SetClosedFd().
60
61 Dart_Port isolate_port() const { return isolate_port_; }
62
63 Dart_Port port() const { return port_; }
64 void set_port(Dart_Port port) { port_ = port; }
65
66 uint8_t* udp_receive_buffer() const { return udp_receive_buffer_; }
67 void set_udp_receive_buffer(uint8_t* buffer) { udp_receive_buffer_ = buffer; }
68
69 static bool Initialize();
70
71 // Creates a socket which is bound and connected. The port to connect to is
72 // specified as the port component of the passed RawAddr structure.
73 static intptr_t CreateConnect(const RawAddr& addr);
74 static intptr_t CreateUnixDomainConnect(const RawAddr& addr);
75 // Creates a socket which is bound and connected. The port to connect to is
76 // specified as the port component of the passed RawAddr structure.
77 static intptr_t CreateBindConnect(const RawAddr& addr,
78 const RawAddr& source_addr);
80 const RawAddr& source_addr);
81 // Creates a datagram socket which is bound. The port to bind
82 // to is specified as the port component of the RawAddr structure.
83 static intptr_t CreateBindDatagram(const RawAddr& addr,
84 bool reuseAddress,
85 bool reusePort,
86 int ttl = 1);
87
88 static CObject* LookupRequest(const CObjectArray& request);
89 static CObject* ListInterfacesRequest(const CObjectArray& request);
90 static CObject* ReverseLookupRequest(const CObjectArray& request);
91
93
94 static void SetSocketIdNativeField(Dart_Handle handle,
95 intptr_t id,
96 SocketFinalizer finalizer);
97 static void ReuseSocketIdNativeField(Dart_Handle handle,
98 Socket* socket,
99 SocketFinalizer finalizer);
101
102 static bool short_socket_read() { return short_socket_read_; }
104 short_socket_read_ = short_socket_read;
105 }
106 static bool short_socket_write() { return short_socket_write_; }
108 short_socket_write_ = short_socket_write;
109 }
110
111 static bool IsSignalSocketFlag(intptr_t flag) {
112 return ((flag & (0x1 << kInternalSignalSocket)) != 0);
113 }
114
115 private:
116 ~Socket() {
117 ASSERT(fd_ == kClosedFd);
118 free(udp_receive_buffer_);
119 udp_receive_buffer_ = nullptr;
120 }
121
122 static constexpr int kClosedFd = -1;
123
124 static bool short_socket_read_;
125 static bool short_socket_write_;
126
127 intptr_t fd_;
128 Dart_Port isolate_port_;
129 Dart_Port port_;
130 uint8_t* udp_receive_buffer_;
131
132 friend class ReferenceCounted<Socket>;
134};
135
137 public:
138 static constexpr intptr_t kTemporaryFailure = -2;
139
140 static intptr_t Accept(intptr_t fd);
141
142 // Creates a socket which is bound and listens. The port to listen on is
143 // specified in the port component of the passed RawAddr structure.
144 //
145 // Returns a positive integer if the call is successful. In case of failure
146 // it returns:
147 //
148 // -1: system error (errno set)
149 // -5: invalid bindAddress
150 static intptr_t CreateBindListen(const RawAddr& addr,
151 intptr_t backlog,
152 bool v6_only = false);
154 intptr_t backlog);
155
156 // Start accepting on a newly created listening socket. If it was unable to
157 // start accepting incoming sockets, the fd is invalidated.
158 static bool StartAccept(intptr_t fd);
159
160 private:
161 DISALLOW_ALLOCATION();
162 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket);
163};
164
166 public:
168 : sockets_by_port_(SameIntptrValue, kInitialSocketsCount),
169 sockets_by_fd_(SameIntptrValue, kInitialSocketsCount),
170 unix_domain_sockets_(nullptr),
171 mutex_() {}
172
173 ~ListeningSocketRegistry() { CloseAllSafe(); }
174
175 static void Initialize();
176
178
179 static void Cleanup();
180
181 // Bind `socket_object` to `addr`.
182 // Return Dart_True() if succeed.
183 // This function should be called from a dart runtime call in order to create
184 // a new (potentially shared) socket.
187 intptr_t backlog,
188 bool v6_only,
189 bool shared);
190 // Bind unix domain socket`socket_object` to `path`.
191 // Return Dart_True() if succeed.
192 // This function should be called from a dart runtime call in order to create
193 // a new socket.
195 Namespace* namespc,
196 const char* path,
197 intptr_t backlog,
198 bool shared);
199
200 // This should be called from the event handler for every kCloseEvent it gets
201 // on listening sockets.
202 //
203 // Returns `true` if the last reference has been dropped and the underlying
204 // socket can be closed.
205 //
206 // The caller is responsible for obtaining the mutex first, before calling
207 // this function.
208 bool CloseSafe(Socket* socketfd);
209
210 Mutex* mutex() { return &mutex_; }
211
212 private:
213 struct OSSocket {
214 RawAddr address;
215 int port;
216 bool v6_only;
217 bool shared;
218 int ref_count;
219 intptr_t fd;
220
221 // Only applicable to Unix domain socket, where address.addr.sa_family
222 // == AF_UNIX.
223 Namespace* namespc;
224
225 // Singly linked lists of OSSocket instances which listen on the same port
226 // but on different addresses.
227 OSSocket* next;
228
229 OSSocket(RawAddr address,
230 int port,
231 bool v6_only,
232 bool shared,
233 Socket* socketfd,
234 Namespace* namespc)
235 : address(address),
236 port(port),
237 v6_only(v6_only),
238 shared(shared),
239 ref_count(0),
240 namespc(namespc),
241 next(nullptr) {
242 fd = socketfd->fd();
243 }
244 };
245
246 static constexpr intptr_t kInitialSocketsCount = 8;
247
248 OSSocket* FindOSSocketWithAddress(OSSocket* current, const RawAddr& addr) {
249 while (current != nullptr) {
250 if (SocketAddress::AreAddressesEqual(current->address, addr)) {
251 return current;
252 }
253 current = current->next;
254 }
255 return nullptr;
256 }
257
258 OSSocket* FindOSSocketWithPath(OSSocket* current,
259 Namespace* namespc,
260 const char* path) {
261 while (current != nullptr) {
262 ASSERT(current->address.addr.sa_family == AF_UNIX);
263#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
264 bool condition;
265 if (path[0] == '\0') {
266 condition = current->address.un.sun_path[0] == '\0' &&
267 strcmp(&(current->address.un.sun_path[1]), path + 1) == 0;
268 } else {
269 condition =
270 File::AreIdentical(current->namespc, current->address.un.sun_path,
271 namespc, path) == File::kIdentical;
272 }
273 if (condition) {
274 return current;
275 }
276#else
277 if (File::AreIdentical(current->namespc, current->address.un.sun_path,
278 namespc, path) == File::kIdentical) {
279 return current;
280 }
281#endif // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
282 current = current->next;
283 }
284 return nullptr;
285 }
286
287 static bool SameIntptrValue(void* key1, void* key2) {
288 return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2);
289 }
290
291 static uint32_t GetHashmapHashFromIntptr(intptr_t i) {
292 return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF);
293 }
294
295 static void* GetHashmapKeyFromIntptr(intptr_t i) {
296 return reinterpret_cast<void*>(i + 1);
297 }
298
299 OSSocket* LookupByPort(intptr_t port);
300 void InsertByPort(intptr_t port, OSSocket* socket);
301 void RemoveByPort(intptr_t port);
302
303 OSSocket* LookupByFd(Socket* fd);
304 void InsertByFd(Socket* fd, OSSocket* socket);
305 void RemoveByFd(Socket* fd);
306
307 bool CloseOneSafe(OSSocket* os_socket, Socket* socket);
308 void CloseAllSafe();
309
310 SimpleHashMap sockets_by_port_;
311 SimpleHashMap sockets_by_fd_;
312
313 OSSocket* unix_domain_sockets_;
314
315 Mutex mutex_;
316
317 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry);
318};
319
320} // namespace bin
321} // namespace dart
322
323#endif // RUNTIME_BIN_SOCKET_H_
static float next(float f)
@ kIdentical
Definition: file.h:84
static Identical AreIdentical(Namespace *namespc_1, const char *file_1, Namespace *namespc_2, const char *file_2)
Dart_Handle CreateBindListen(Dart_Handle socket_object, RawAddr addr, intptr_t backlog, bool v6_only, bool shared)
Definition: socket.cc:94
bool CloseSafe(Socket *socketfd)
Definition: socket.cc:350
Dart_Handle CreateUnixDomainBindListen(Dart_Handle socket_object, Namespace *namespc, const char *path, intptr_t backlog, bool shared)
Definition: socket.cc:197
static ListeningSocketRegistry * Instance()
Definition: socket.cc:38
static intptr_t CreateBindListen(const RawAddr &addr, intptr_t backlog, bool v6_only=false)
static intptr_t Accept(intptr_t fd)
static constexpr intptr_t kTemporaryFailure
Definition: socket.h:138
static bool StartAccept(intptr_t fd)
static intptr_t CreateUnixDomainBindListen(const RawAddr &addr, intptr_t backlog)
static bool AreAddressesEqual(const RawAddr &a, const RawAddr &b)
Definition: socket_base.cc:80
@ kReverseLookupRequest
Definition: socket.h:32
@ kListInterfacesRequest
Definition: socket.h:31
static bool IsSignalSocketFlag(intptr_t flag)
Definition: socket.h:111
static CObject * ListInterfacesRequest(const CObjectArray &request)
Definition: socket.cc:1134
intptr_t fd() const
Definition: socket.h:52
static bool short_socket_read()
Definition: socket.h:102
Dart_Port isolate_port() const
Definition: socket.h:61
static void set_short_socket_read(bool short_socket_read)
Definition: socket.h:103
static Dart_Port GetServicePort()
void set_udp_receive_buffer(uint8_t *buffer)
Definition: socket.h:67
@ kInternalSignalSocket
Definition: socket.h:47
static CObject * ReverseLookupRequest(const CObjectArray &request)
Definition: socket.cc:1103
static bool short_socket_write()
Definition: socket.h:106
static intptr_t CreateUnixDomainConnect(const RawAddr &addr)
uint8_t * udp_receive_buffer() const
Definition: socket.h:66
static void SetSocketIdNativeField(Dart_Handle handle, intptr_t id, SocketFinalizer finalizer)
Definition: socket.cc:1489
Dart_Port port() const
Definition: socket.h:63
static Socket * GetSocketIdNativeField(Dart_Handle socket)
Definition: socket.cc:1496
static intptr_t CreateConnect(const RawAddr &addr)
void set_port(Dart_Port port)
Definition: socket.h:64
static intptr_t CreateBindDatagram(const RawAddr &addr, bool reuseAddress, bool reusePort, int ttl=1)
static void ReuseSocketIdNativeField(Dart_Handle handle, Socket *socket, SocketFinalizer finalizer)
Definition: socket.cc:1456
Socket(intptr_t fd)
static CObject * LookupRequest(const CObjectArray &request)
Definition: socket.cc:1057
static bool Initialize()
static intptr_t CreateBindConnect(const RawAddr &addr, const RawAddr &source_addr)
@ kFinalizerListening
Definition: socket.h:37
static intptr_t CreateUnixDomainBindConnect(const RawAddr &addr, const RawAddr &source_addr)
static void set_short_socket_write(bool short_socket_write)
Definition: socket.h:107
int64_t Dart_Port
Definition: dart_api.h:1525
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
#define ASSERT(E)
FlutterSemanticsFlag flag
Definition: dart_vm.cc:33
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
Definition: switches.h:87
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581