Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: runtime/bin/socket.h

Issue 2797993005: Re-land socket refactor with fixes for Windows. (Closed)
Patch Set: Rebased + reverted original revert Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/bin/process_win.cc ('k') | runtime/bin/socket.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
13 // Declare the OS-specific types ahead of defining the generic class.
14 #if defined(HOST_OS_ANDROID)
15 #include "bin/socket_android.h"
16 #elif defined(HOST_OS_FUCHSIA)
17 #include "bin/socket_fuchsia.h"
18 #elif defined(HOST_OS_LINUX)
19 #include "bin/socket_linux.h"
20 #elif defined(HOST_OS_MACOS)
21 #include "bin/socket_macos.h"
22 #elif defined(HOST_OS_WINDOWS)
23 #include "bin/socket_win.h"
24 #else
25 #error Unknown target os.
26 #endif
27
28 #include "bin/builtin.h" 12 #include "bin/builtin.h"
29 #include "bin/dartutils.h" 13 #include "bin/dartutils.h"
30 #include "bin/reference_counting.h" 14 #include "bin/reference_counting.h"
15 #include "bin/socket_base.h"
31 #include "bin/thread.h" 16 #include "bin/thread.h"
32 #include "bin/utils.h" 17 #include "bin/utils.h"
33 #include "platform/hashmap.h" 18 #include "platform/hashmap.h"
34 19
35 namespace dart { 20 namespace dart {
36 namespace bin { 21 namespace bin {
37 22
38 union RawAddr { 23 // TODO(bkonyi): Socket should also inherit from SocketBase once it is
39 struct sockaddr_in in; 24 // refactored to use instance methods when possible.
40 struct sockaddr_in6 in6;
41 struct sockaddr_storage ss;
42 struct sockaddr addr;
43 };
44
45 class SocketAddress {
46 public:
47 enum {
48 TYPE_ANY = -1,
49 TYPE_IPV4,
50 TYPE_IPV6,
51 };
52
53 enum {
54 ADDRESS_LOOPBACK_IP_V4,
55 ADDRESS_LOOPBACK_IP_V6,
56 ADDRESS_ANY_IP_V4,
57 ADDRESS_ANY_IP_V6,
58 ADDRESS_FIRST = ADDRESS_LOOPBACK_IP_V4,
59 ADDRESS_LAST = ADDRESS_ANY_IP_V6,
60 };
61
62 explicit SocketAddress(struct sockaddr* sa);
63
64 ~SocketAddress() {}
65
66 int GetType() {
67 if (addr_.ss.ss_family == AF_INET6) {
68 return TYPE_IPV6;
69 }
70 return TYPE_IPV4;
71 }
72
73 const char* as_string() const { return as_string_; }
74 const RawAddr& addr() const { return addr_; }
75
76 static intptr_t GetAddrLength(const RawAddr& addr) {
77 ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6));
78 return (addr.ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6)
79 : sizeof(struct sockaddr_in);
80 }
81
82 static intptr_t GetInAddrLength(const RawAddr& addr) {
83 ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6));
84 return (addr.ss.ss_family == AF_INET6) ? sizeof(struct in6_addr)
85 : sizeof(struct in_addr);
86 }
87
88 static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) {
89 if (a.ss.ss_family == AF_INET) {
90 if (b.ss.ss_family != AF_INET) {
91 return false;
92 }
93 return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0;
94 } else if (a.ss.ss_family == AF_INET6) {
95 if (b.ss.ss_family != AF_INET6) {
96 return false;
97 }
98 return memcmp(&a.in6.sin6_addr, &b.in6.sin6_addr,
99 sizeof(a.in6.sin6_addr)) == 0;
100 } else {
101 UNREACHABLE();
102 return false;
103 }
104 }
105
106 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) {
107 Dart_TypedData_Type data_type;
108 uint8_t* data = NULL;
109 intptr_t len;
110 Dart_Handle result = Dart_TypedDataAcquireData(
111 obj, &data_type, reinterpret_cast<void**>(&data), &len);
112 if (Dart_IsError(result)) {
113 Dart_PropagateError(result);
114 }
115 if ((data_type != Dart_TypedData_kUint8) ||
116 ((len != sizeof(in_addr)) && (len != sizeof(in6_addr)))) {
117 Dart_PropagateError(
118 Dart_NewApiError("Unexpected type for socket address"));
119 }
120 memset(reinterpret_cast<void*>(addr), 0, sizeof(RawAddr));
121 if (len == sizeof(in_addr)) {
122 addr->in.sin_family = AF_INET;
123 memmove(reinterpret_cast<void*>(&addr->in.sin_addr), data, len);
124 } else {
125 ASSERT(len == sizeof(in6_addr));
126 addr->in6.sin6_family = AF_INET6;
127 memmove(reinterpret_cast<void*>(&addr->in6.sin6_addr), data, len);
128 }
129 Dart_TypedDataReleaseData(obj);
130 }
131
132 static int16_t FromType(int type) {
133 if (type == TYPE_ANY) {
134 return AF_UNSPEC;
135 }
136 if (type == TYPE_IPV4) {
137 return AF_INET;
138 }
139 ASSERT((type == TYPE_IPV6) && "Invalid type");
140 return AF_INET6;
141 }
142
143 static void SetAddrPort(RawAddr* addr, intptr_t port) {
144 if (addr->ss.ss_family == AF_INET) {
145 addr->in.sin_port = htons(port);
146 } else {
147 addr->in6.sin6_port = htons(port);
148 }
149 }
150
151 static intptr_t GetAddrPort(const RawAddr& addr) {
152 if (addr.ss.ss_family == AF_INET) {
153 return ntohs(addr.in.sin_port);
154 } else {
155 return ntohs(addr.in6.sin6_port);
156 }
157 }
158
159 static Dart_Handle ToTypedData(const RawAddr& addr) {
160 int len = GetInAddrLength(addr);
161 Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len);
162 if (Dart_IsError(result)) {
163 Dart_PropagateError(result);
164 }
165 Dart_Handle err;
166 if (addr.addr.sa_family == AF_INET6) {
167 err = Dart_ListSetAsBytes(
168 result, 0, reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr),
169 len);
170 } else {
171 err = Dart_ListSetAsBytes(
172 result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len);
173 }
174 if (Dart_IsError(err)) {
175 Dart_PropagateError(err);
176 }
177 return result;
178 }
179
180 static CObjectUint8Array* ToCObject(const RawAddr& addr) {
181 int in_addr_len = SocketAddress::GetInAddrLength(addr);
182 const void* in_addr;
183 CObjectUint8Array* data =
184 new CObjectUint8Array(CObject::NewUint8Array(in_addr_len));
185 if (addr.addr.sa_family == AF_INET6) {
186 in_addr = reinterpret_cast<const void*>(&addr.in6.sin6_addr);
187 } else {
188 in_addr = reinterpret_cast<const void*>(&addr.in.sin_addr);
189 }
190 memmove(data->Buffer(), in_addr, in_addr_len);
191 return data;
192 }
193
194 private:
195 char as_string_[INET6_ADDRSTRLEN];
196 RawAddr addr_;
197
198 DISALLOW_COPY_AND_ASSIGN(SocketAddress);
199 };
200
201
202 class InterfaceSocketAddress {
203 public:
204 InterfaceSocketAddress(struct sockaddr* sa,
205 const char* interface_name,
206 intptr_t interface_index)
207 : socket_address_(new SocketAddress(sa)),
208 interface_name_(interface_name),
209 interface_index_(interface_index) {}
210
211 ~InterfaceSocketAddress() { delete socket_address_; }
212
213 SocketAddress* socket_address() const { return socket_address_; }
214 const char* interface_name() const { return interface_name_; }
215 int interface_index() const { return interface_index_; }
216
217 private:
218 SocketAddress* socket_address_;
219 const char* interface_name_;
220 intptr_t interface_index_;
221
222 DISALLOW_COPY_AND_ASSIGN(InterfaceSocketAddress);
223 };
224
225
226 template <typename T>
227 class AddressList {
228 public:
229 explicit AddressList(intptr_t count)
230 : count_(count), addresses_(new T*[count_]) {}
231
232 ~AddressList() {
233 for (intptr_t i = 0; i < count_; i++) {
234 delete addresses_[i];
235 }
236 delete[] addresses_;
237 }
238
239 intptr_t count() const { return count_; }
240 T* GetAt(intptr_t i) const { return addresses_[i]; }
241 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; }
242
243 private:
244 const intptr_t count_;
245 T** addresses_;
246
247 DISALLOW_COPY_AND_ASSIGN(AddressList);
248 };
249
250 25
251 // We write Sockets into the native field of the _NativeSocket object 26 // We write Sockets into the native field of the _NativeSocket object
252 // on the Dart side. They are allocated in SetSocketIdNativeField(), and are 27 // on the Dart side. They are allocated in SetSocketIdNativeField(), and are
253 // deallocated either from the finalizer attached to _NativeSockets there, or 28 // deallocated either from the finalizer attached to _NativeSockets there, or
254 // from the eventhandler, whichever drops the last reference. 29 // from the eventhandler, whichever drops the last reference.
255 class Socket : public ReferenceCounted<Socket> { 30 class Socket : public ReferenceCounted<Socket> {
256 public: 31 public:
257 enum SocketRequest { 32 enum SocketRequest {
258 kLookupRequest = 0, 33 kLookupRequest = 0,
259 kListInterfacesRequest = 1, 34 kListInterfacesRequest = 1,
260 kReverseLookupRequest = 2, 35 kReverseLookupRequest = 2,
261 }; 36 };
262 37
263 enum SocketFinalizer { 38 enum SocketFinalizer {
264 kFinalizerNormal, 39 kFinalizerNormal,
265 kFinalizerListening, 40 kFinalizerListening,
266 kFinalizerStdio, 41 kFinalizerStdio,
267 }; 42 };
268 43
269 explicit Socket(intptr_t fd); 44 explicit Socket(intptr_t fd);
270 45
271 intptr_t fd() const { return fd_; } 46 intptr_t fd() const { return fd_; }
272 void SetClosedFd(); 47 void SetClosedFd();
273 48
274 Dart_Port port() const { return port_; } 49 Dart_Port port() const { return port_; }
275 void set_port(Dart_Port port) { port_ = port; } 50 void set_port(Dart_Port port) { port_ = port; }
276 51
277 // TODO(dart:io): Convert these to instance methods where possible.
278 static bool Initialize(); 52 static bool Initialize();
279 static intptr_t Available(intptr_t fd); 53
280 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes);
281 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes);
282 // Send data on a socket. The port to send to is specified in the port
283 // component of the passed RawAddr structure. The RawAddr structure is only
284 // used for datagram sockets.
285 static intptr_t SendTo(intptr_t fd,
286 const void* buffer,
287 intptr_t num_bytes,
288 const RawAddr& addr);
289 static intptr_t RecvFrom(intptr_t fd,
290 void* buffer,
291 intptr_t num_bytes,
292 RawAddr* addr);
293 // Creates a socket which is bound and connected. The port to connect to is 54 // Creates a socket which is bound and connected. The port to connect to is
294 // specified as the port component of the passed RawAddr structure. 55 // specified as the port component of the passed RawAddr structure.
295 static intptr_t CreateConnect(const RawAddr& addr); 56 static intptr_t CreateConnect(const RawAddr& addr);
296 // Creates a socket which is bound and connected. The port to connect to is 57 // Creates a socket which is bound and connected. The port to connect to is
297 // specified as the port component of the passed RawAddr structure. 58 // specified as the port component of the passed RawAddr structure.
298 static intptr_t CreateBindConnect(const RawAddr& addr, 59 static intptr_t CreateBindConnect(const RawAddr& addr,
299 const RawAddr& source_addr); 60 const RawAddr& source_addr);
300 // Returns true if the given error-number is because the system was not able
301 // to bind the socket to a specific IP.
302 static bool IsBindError(intptr_t error_number);
303 // Creates a datagram socket which is bound. The port to bind 61 // Creates a datagram socket which is bound. The port to bind
304 // to is specified as the port component of the RawAddr structure. 62 // to is specified as the port component of the RawAddr structure.
305 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress); 63 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress);
306 static intptr_t GetPort(intptr_t fd);
307 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port);
308 static void GetError(intptr_t fd, OSError* os_error);
309 static int GetType(intptr_t fd);
310 static intptr_t GetStdioHandle(intptr_t num);
311 static void Close(intptr_t fd);
312 static bool GetNoDelay(intptr_t fd, bool* enabled);
313 static bool SetNoDelay(intptr_t fd, bool enabled);
314 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled);
315 static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled);
316 static bool GetMulticastHops(intptr_t fd, intptr_t protocol, int* value);
317 static bool SetMulticastHops(intptr_t fd, intptr_t protocol, int value);
318 static bool GetBroadcast(intptr_t fd, bool* value);
319 static bool SetBroadcast(intptr_t fd, bool value);
320 static bool JoinMulticast(intptr_t fd,
321 const RawAddr& addr,
322 const RawAddr& interface,
323 int interfaceIndex);
324 static bool LeaveMulticast(intptr_t fd,
325 const RawAddr& addr,
326 const RawAddr& interface,
327 int interfaceIndex);
328
329 // Perform a hostname lookup. Returns a AddressList of SocketAddress's.
330 static AddressList<SocketAddress>* LookupAddress(const char* host,
331 int type,
332 OSError** os_error);
333
334 static bool ReverseLookup(const RawAddr& addr,
335 char* host,
336 intptr_t host_len,
337 OSError** os_error);
338
339 static bool ParseAddress(int type, const char* address, RawAddr* addr);
340 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len);
341
342 // Whether ListInterfaces is supported.
343 static bool ListInterfacesSupported();
344
345 // List interfaces. Returns a AddressList of InterfaceSocketAddress's.
346 static AddressList<InterfaceSocketAddress>* ListInterfaces(
347 int type,
348 OSError** os_error);
349 64
350 static CObject* LookupRequest(const CObjectArray& request); 65 static CObject* LookupRequest(const CObjectArray& request);
351 static CObject* ListInterfacesRequest(const CObjectArray& request); 66 static CObject* ListInterfacesRequest(const CObjectArray& request);
352 static CObject* ReverseLookupRequest(const CObjectArray& request); 67 static CObject* ReverseLookupRequest(const CObjectArray& request);
353 68
354 static Dart_Port GetServicePort(); 69 static Dart_Port GetServicePort();
355 70
356 static void SetSocketIdNativeField(Dart_Handle handle, 71 static void SetSocketIdNativeField(Dart_Handle handle,
357 intptr_t id, 72 intptr_t id,
358 SocketFinalizer finalizer); 73 SocketFinalizer finalizer);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 224
510 Mutex* mutex_; 225 Mutex* mutex_;
511 226
512 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); 227 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry);
513 }; 228 };
514 229
515 } // namespace bin 230 } // namespace bin
516 } // namespace dart 231 } // namespace dart
517 232
518 #endif // RUNTIME_BIN_SOCKET_H_ 233 #endif // RUNTIME_BIN_SOCKET_H_
OLDNEW
« no previous file with comments | « runtime/bin/process_win.cc ('k') | runtime/bin/socket.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698