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

Side by Side Diff: runtime/bin/socket_common.cc

Issue 2780063002: Pulled a significant portion of Socket implementation into BaseSocket in order to prepare for the s… (Closed)
Patch Set: 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
OLDNEW
(Empty)
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 #if !defined(DART_IO_DISABLED)
6
7 #include "bin/socket_common.h"
8 #include "bin/socket.h"
9
10 #include "bin/dartutils.h"
11 #include "bin/io_buffer.h"
12 #include "bin/isolate_data.h"
13 #include "bin/lockers.h"
14 #include "bin/thread.h"
15 #include "bin/utils.h"
16
17 #include "include/dart_api.h"
18
19 #include "platform/globals.h"
20 #include "platform/utils.h"
21
22 namespace dart {
23 namespace bin {
24
25 static const int kSocketIdNativeField = 0;
26
27 bool short_socket_read = false;
28
29 bool short_socket_write = false;
30
31 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
32 const char* address =
33 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
34 ASSERT(address != NULL);
35 RawAddr raw;
36 memset(&raw, 0, sizeof(raw));
37 int type = strchr(address, ':') == NULL ? SocketAddress::TYPE_IPV4
38 : SocketAddress::TYPE_IPV6;
39 if (type == SocketAddress::TYPE_IPV4) {
40 raw.addr.sa_family = AF_INET;
41 } else {
42 raw.addr.sa_family = AF_INET6;
43 }
44 bool ok = BaseSocket::ParseAddress(type, address, &raw);
45 if (!ok) {
46 Dart_SetReturnValue(args, Dart_Null());
47 } else {
48 Dart_SetReturnValue(args, SocketAddress::ToTypedData(raw));
49 }
50 }
51
52
53 void FUNCTION_NAME(NetworkInterface_ListSupported)(Dart_NativeArguments args) {
54 Dart_SetReturnValue(args, Dart_NewBoolean(Socket::ListInterfacesSupported()));
55 }
56
57
58 void FUNCTION_NAME(BaseSocket_IsBindError)(Dart_NativeArguments args) {
59 intptr_t error_number =
60 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
61 bool is_bind_error = BaseSocket::IsBindError(error_number);
62 Dart_SetReturnValue(args, is_bind_error ? Dart_True() : Dart_False());
63 }
64
65
66 void FUNCTION_NAME(BaseSocket_Available)(Dart_NativeArguments args) {
67 intptr_t socket =
68 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
69 intptr_t available = BaseSocket::Available(socket);
70 if (available >= 0) {
71 Dart_SetReturnValue(args, Dart_NewInteger(available));
72 } else {
73 // Available failed. Mark socket as having data, to trigger a future read
74 // event where the actual error can be reported.
75 Dart_SetReturnValue(args, Dart_NewInteger(1));
76 }
77 }
78
79
80 void FUNCTION_NAME(BaseSocket_Read)(Dart_NativeArguments args) {
81 intptr_t socket =
82 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
83 int64_t length = 0;
84 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) {
85 if (short_socket_read) {
86 length = (length + 1) / 2;
87 }
88 uint8_t* buffer = NULL;
89 Dart_Handle result = IOBuffer::Allocate(length, &buffer);
90 if (Dart_IsError(result)) {
91 Dart_PropagateError(result);
92 }
93 ASSERT(buffer != NULL);
94 intptr_t bytes_read = BaseSocket::Read(socket, buffer, length);
95 if (bytes_read == length) {
96 Dart_SetReturnValue(args, result);
97 } else if (bytes_read > 0) {
98 uint8_t* new_buffer = NULL;
99 Dart_Handle new_result = IOBuffer::Allocate(bytes_read, &new_buffer);
100 if (Dart_IsError(new_result)) {
101 Dart_PropagateError(new_result);
102 }
103 ASSERT(new_buffer != NULL);
104 memmove(new_buffer, buffer, bytes_read);
105 Dart_SetReturnValue(args, new_result);
106 } else if (bytes_read == 0) {
107 // On MacOS when reading from a tty Ctrl-D will result in reading one
108 // less byte then reported as available.
109 Dart_SetReturnValue(args, Dart_Null());
110 } else {
111 ASSERT(bytes_read == -1);
112 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
113 }
114 } else {
115 OSError os_error(-1, "Invalid argument", OSError::kUnknown);
116 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
117 }
118 }
119
120
121 void FUNCTION_NAME(BaseSocket_RecvFrom)(Dart_NativeArguments args) {
122 intptr_t socket =
123 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
124
125 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can
126 // handle 64k datagrams.
127 IsolateData* isolate_data =
128 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
129 if (isolate_data->udp_receive_buffer == NULL) {
130 isolate_data->udp_receive_buffer =
131 reinterpret_cast<uint8_t*>(malloc(65536));
132 }
133 RawAddr addr;
134 intptr_t bytes_read = BaseSocket::RecvFrom(
135 socket, isolate_data->udp_receive_buffer, 65536, &addr);
136 if (bytes_read == 0) {
137 Dart_SetReturnValue(args, Dart_Null());
138 return;
139 }
140 if (bytes_read < 0) {
141 ASSERT(bytes_read == -1);
142 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
143 return;
144 }
145 // Datagram data read. Copy into buffer of the exact size,
146 ASSERT(bytes_read > 0);
147 uint8_t* data_buffer = NULL;
148 Dart_Handle data = IOBuffer::Allocate(bytes_read, &data_buffer);
149 if (Dart_IsError(data)) {
150 Dart_PropagateError(data);
151 }
152 ASSERT(data_buffer != NULL);
153 memmove(data_buffer, isolate_data->udp_receive_buffer, bytes_read);
154
155 // Get the port and clear it in the sockaddr structure.
156 int port = SocketAddress::GetAddrPort(addr);
157 if (addr.addr.sa_family == AF_INET) {
158 addr.in.sin_port = 0;
159 } else {
160 ASSERT(addr.addr.sa_family == AF_INET6);
161 addr.in6.sin6_port = 0;
162 }
163 // Format the address to a string using the numeric format.
164 char numeric_address[INET6_ADDRSTRLEN];
165 BaseSocket::FormatNumericAddress(addr, numeric_address, INET6_ADDRSTRLEN);
166
167 // Create a Datagram object with the data and sender address and port.
168 const int kNumArgs = 4;
169 Dart_Handle dart_args[kNumArgs];
170 dart_args[0] = data;
171 dart_args[1] = Dart_NewStringFromCString(numeric_address);
172 if (Dart_IsError(dart_args[1])) {
173 Dart_PropagateError(dart_args[1]);
174 }
175 dart_args[2] = SocketAddress::ToTypedData(addr);
176 dart_args[3] = Dart_NewInteger(port);
177 if (Dart_IsError(dart_args[3])) {
178 Dart_PropagateError(dart_args[3]);
179 }
180 // TODO(sgjesse): Cache the _makeDatagram function somewhere.
181 Dart_Handle io_lib = Dart_LookupLibrary(DartUtils::NewString("dart:io"));
182 if (Dart_IsError(io_lib)) {
183 Dart_PropagateError(io_lib);
184 }
185 Dart_Handle result = Dart_Invoke(
186 io_lib, DartUtils::NewString("_makeDatagram"), kNumArgs, dart_args);
187 Dart_SetReturnValue(args, result);
188 }
189
190
191 void FUNCTION_NAME(BaseSocket_WriteList)(Dart_NativeArguments args) {
192 intptr_t socket =
193 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
194 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
195 ASSERT(Dart_IsList(buffer_obj));
196 intptr_t offset = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
197 intptr_t length = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
198 bool short_write = false;
199 if (short_socket_write) {
200 if (length > 1) {
201 short_write = true;
202 }
203 length = (length + 1) / 2;
204 }
205 Dart_TypedData_Type type;
206 uint8_t* buffer = NULL;
207 intptr_t len;
208 Dart_Handle result = Dart_TypedDataAcquireData(
209 buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len);
210 if (Dart_IsError(result)) {
211 Dart_PropagateError(result);
212 }
213 ASSERT((offset + length) <= len);
214 buffer += offset;
215 intptr_t bytes_written = BaseSocket::Write(socket, buffer, length);
216 if (bytes_written >= 0) {
217 Dart_TypedDataReleaseData(buffer_obj);
218 if (short_write) {
219 // If the write was forced 'short', indicate by returning the negative
220 // number of bytes. A forced short write may not trigger a write event.
221 Dart_SetReturnValue(args, Dart_NewInteger(-bytes_written));
222 } else {
223 Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
224 }
225 } else {
226 // Extract OSError before we release data, as it may override the error.
227 OSError os_error;
228 Dart_TypedDataReleaseData(buffer_obj);
229 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
230 }
231 }
232
233
234 void FUNCTION_NAME(BaseSocket_SendTo)(Dart_NativeArguments args) {
235 intptr_t socket =
236 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
237 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
238 intptr_t offset = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
239 intptr_t length = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
240 Dart_Handle address_obj = Dart_GetNativeArgument(args, 4);
241 ASSERT(Dart_IsList(address_obj));
242 RawAddr addr;
243 SocketAddress::GetSockAddr(address_obj, &addr);
244 int64_t port = DartUtils::GetInt64ValueCheckRange(
245 Dart_GetNativeArgument(args, 5), 0, 65535);
246 SocketAddress::SetAddrPort(&addr, port);
247 Dart_TypedData_Type type;
248 uint8_t* buffer = NULL;
249 intptr_t len;
250 Dart_Handle result = Dart_TypedDataAcquireData(
251 buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len);
252 if (Dart_IsError(result)) {
253 Dart_PropagateError(result);
254 }
255 ASSERT((offset + length) <= len);
256 buffer += offset;
257 intptr_t bytes_written = BaseSocket::SendTo(socket, buffer, length, addr);
258 if (bytes_written >= 0) {
259 Dart_TypedDataReleaseData(buffer_obj);
260 Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
261 } else {
262 // Extract OSError before we release data, as it may override the error.
263 OSError os_error;
264 Dart_TypedDataReleaseData(buffer_obj);
265 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
266 }
267 }
268
269
270 void FUNCTION_NAME(BaseSocket_GetPort)(Dart_NativeArguments args) {
271 intptr_t socket =
272 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
273 OSError os_error;
274 intptr_t port = BaseSocket::GetPort(socket);
275 if (port > 0) {
276 Dart_SetReturnValue(args, Dart_NewInteger(port));
277 } else {
278 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
279 }
280 }
281
282
283 void FUNCTION_NAME(BaseSocket_GetRemotePeer)(Dart_NativeArguments args) {
284 intptr_t socket =
285 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
286 OSError os_error;
287 intptr_t port = 0;
288 SocketAddress* addr = BaseSocket::GetRemotePeer(socket, &port);
289 if (addr != NULL) {
290 Dart_Handle list = Dart_NewList(2);
291
292 Dart_Handle entry = Dart_NewList(3);
293 Dart_ListSetAt(entry, 0, Dart_NewInteger(addr->GetType()));
294 Dart_ListSetAt(entry, 1, Dart_NewStringFromCString(addr->as_string()));
295
296 RawAddr raw = addr->addr();
297 Dart_ListSetAt(entry, 2, SocketAddress::ToTypedData(raw));
298
299 Dart_ListSetAt(list, 0, entry);
300 Dart_ListSetAt(list, 1, Dart_NewInteger(port));
301 Dart_SetReturnValue(args, list);
302 delete addr;
303 } else {
304 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
305 }
306 }
307
308
309 void FUNCTION_NAME(BaseSocket_GetError)(Dart_NativeArguments args) {
310 intptr_t socket =
311 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
312 OSError os_error;
313 BaseSocket::GetError(socket, &os_error);
314 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
315 }
316
317
318 void FUNCTION_NAME(BaseSocket_GetType)(Dart_NativeArguments args) {
319 intptr_t socket =
320 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
321 OSError os_error;
322 intptr_t type = BaseSocket::GetType(socket);
323 if (type >= 0) {
324 Dart_SetReturnValue(args, Dart_NewInteger(type));
325 } else {
326 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
327 }
328 }
329
330
331 void FUNCTION_NAME(BaseSocket_GetStdioHandle)(Dart_NativeArguments args) {
332 int64_t num =
333 DartUtils::GetInt64ValueCheckRange(Dart_GetNativeArgument(args, 1), 0, 2);
334 intptr_t socket = BaseSocket::GetStdioHandle(num);
335 BaseSocket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
336 Dart_SetReturnValue(args, Dart_NewBoolean(socket >= 0));
337 }
338
339
340 void FUNCTION_NAME(BaseSocket_GetSocketId)(Dart_NativeArguments args) {
341 intptr_t id =
342 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
343 Dart_SetReturnValue(args, Dart_NewInteger(id));
344 }
345
346
347 void FUNCTION_NAME(BaseSocket_SetSocketId)(Dart_NativeArguments args) {
348 intptr_t id = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
349 BaseSocket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), id);
350 }
351
352
353 void FUNCTION_NAME(BaseSocket_GetOption)(Dart_NativeArguments args) {
354 intptr_t socket =
355 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
356 int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
357 intptr_t protocol = static_cast<intptr_t>(
358 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2)));
359 bool ok = false;
360 switch (option) {
361 case 0: { // TCP_NODELAY.
362 bool enabled;
363 ok = BaseSocket::GetNoDelay(socket, &enabled);
364 if (ok) {
365 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
366 }
367 break;
368 }
369 case 1: { // IP_MULTICAST_LOOP.
370 bool enabled;
371 ok = BaseSocket::GetMulticastLoop(socket, protocol, &enabled);
372 if (ok) {
373 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
374 }
375 break;
376 }
377 case 2: { // IP_MULTICAST_TTL.
378 int value;
379 ok = BaseSocket::GetMulticastHops(socket, protocol, &value);
380 if (ok) {
381 Dart_SetReturnValue(args, Dart_NewInteger(value));
382 }
383 break;
384 }
385 case 3: { // IP_MULTICAST_IF.
386 UNIMPLEMENTED();
387 break;
388 }
389 case 4: { // IP_BROADCAST.
390 bool enabled;
391 ok = BaseSocket::GetBroadcast(socket, &enabled);
392 if (ok) {
393 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
394 }
395 break;
396 }
397 default:
398 UNREACHABLE();
399 break;
400 }
401 // In case of failure the return value is not set above.
402 if (!ok) {
403 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
404 }
405 }
406
407
408 void FUNCTION_NAME(BaseSocket_SetOption)(Dart_NativeArguments args) {
409 bool result = false;
410 intptr_t socket =
411 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
412 int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
413 int64_t protocol = DartUtils::GetInt64ValueCheckRange(
414 Dart_GetNativeArgument(args, 2), SocketAddress::TYPE_IPV4,
415 SocketAddress::TYPE_IPV6);
416 switch (option) {
417 case 0: // TCP_NODELAY.
418 result = BaseSocket::SetNoDelay(
419 socket, DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
420 break;
421 case 1: // IP_MULTICAST_LOOP.
422 result = BaseSocket::SetMulticastLoop(
423 socket, protocol,
424 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
425 break;
426 case 2: // IP_MULTICAST_TTL.
427 result = BaseSocket::SetMulticastHops(
428 socket, protocol,
429 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3)));
430 break;
431 case 3: { // IP_MULTICAST_IF.
432 UNIMPLEMENTED();
433 break;
434 }
435 case 4: // IP_BROADCAST.
436 result = BaseSocket::SetBroadcast(
437 socket, DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
438 break;
439 default:
440 Dart_PropagateError(Dart_NewApiError("Value outside expected range"));
441 break;
442 }
443 if (result) {
444 Dart_SetReturnValue(args, Dart_Null());
445 } else {
446 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
447 }
448 }
449
450
451 void FUNCTION_NAME(BaseSocket_JoinMulticast)(Dart_NativeArguments args) {
452 intptr_t socket =
453 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
454 RawAddr addr;
455 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
456 RawAddr interface;
457 if (Dart_GetNativeArgument(args, 2) != Dart_Null()) {
458 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 2), &interface);
459 }
460 int interfaceIndex =
461 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
462 if (BaseSocket::JoinMulticast(socket, addr, interface, interfaceIndex)) {
463 Dart_SetReturnValue(args, Dart_Null());
464 } else {
465 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
466 }
467 }
468
469
470 void FUNCTION_NAME(BaseSocket_LeaveMulticast)(Dart_NativeArguments args) {
471 intptr_t socket =
472 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
473 RawAddr addr;
474 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
475 RawAddr interface;
476 if (Dart_GetNativeArgument(args, 2) != Dart_Null()) {
477 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 2), &interface);
478 }
479 int interfaceIndex =
480 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
481 if (Socket::LeaveMulticast(socket, addr, interface, interfaceIndex)) {
482 Dart_SetReturnValue(args, Dart_Null());
483 } else {
484 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
485 }
486 }
487
488
489 void BaseSocket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) {
490 Dart_Handle err =
491 Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id);
492 if (Dart_IsError(err)) {
493 Dart_PropagateError(err);
494 }
495 }
496
497
498 intptr_t BaseSocket::GetSocketIdNativeField(Dart_Handle socket_obj) {
499 intptr_t socket = 0;
500 Dart_Handle err =
501 Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &socket);
502 if (Dart_IsError(err)) {
503 Dart_PropagateError(err);
504 }
505 return socket;
506 }
507
508 } // namespace bin
509 } // namespace dart
510
511 #endif // !defined(DART_IO_DISABLED)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698