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

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

Issue 85993002: Add UDP support to dart:io (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed first round of comments Created 7 years 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 | Annotate | Revision Log
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 #include "bin/io_buffer.h" 5 #include "bin/io_buffer.h"
6 #include "bin/socket.h" 6 #include "bin/socket.h"
7 #include "bin/dartutils.h" 7 #include "bin/dartutils.h"
8 #include "bin/thread.h" 8 #include "bin/thread.h"
9 #include "bin/utils.h" 9 #include "bin/utils.h"
10 10
11 #include "platform/globals.h" 11 #include "platform/globals.h"
12 #include "platform/thread.h" 12 #include "platform/thread.h"
13 #include "platform/utils.h" 13 #include "platform/utils.h"
14 14
15 #include "include/dart_api.h" 15 #include "include/dart_api.h"
16 16
17 17
18 namespace dart { 18 namespace dart {
19 namespace bin { 19 namespace bin {
20 20
21 static const int kSocketIdNativeField = 0; 21 static const int kSocketIdNativeField = 0;
22 22
23 dart::Mutex* Socket::mutex_ = new dart::Mutex(); 23 dart::Mutex* Socket::mutex_ = new dart::Mutex();
24 int Socket::service_ports_size_ = 0; 24 int Socket::service_ports_size_ = 0;
25 Dart_Port* Socket::service_ports_ = NULL; 25 Dart_Port* Socket::service_ports_ = NULL;
26 int Socket::service_ports_index_ = 0; 26 int Socket::service_ports_index_ = 0;
27 27
28 // TODO(sgjesse): Make this thread local.
29 unsigned int rand_r_state = 0;
28 30
29 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { 31 static void GetSockAddr(Dart_Handle obj, RawAddr* addr) {
30 Dart_TypedData_Type data_type; 32 Dart_TypedData_Type data_type;
31 uint8_t* data = NULL; 33 uint8_t* data = NULL;
32 intptr_t len; 34 intptr_t len;
33 Dart_Handle result = Dart_TypedDataAcquireData( 35 Dart_Handle result = Dart_TypedDataAcquireData(
34 obj, &data_type, reinterpret_cast<void**>(&data), &len); 36 obj, &data_type, reinterpret_cast<void**>(&data), &len);
35 if (Dart_IsError(result)) Dart_PropagateError(result); 37 if (Dart_IsError(result)) Dart_PropagateError(result);
38 if (data_type != Dart_TypedData_kUint8) {
39 Dart_PropagateError(Dart_NewApiError("Unexpected type for socket address"));
40 }
36 memmove(reinterpret_cast<void *>(addr), data, len); 41 memmove(reinterpret_cast<void *>(addr), data, len);
37 Dart_TypedDataReleaseData(obj); 42 Dart_TypedDataReleaseData(obj);
38 } 43 }
39 44
40 45
41 void FUNCTION_NAME(InternetAddress_Fixed)(Dart_NativeArguments args) { 46 void FUNCTION_NAME(InternetAddress_Fixed)(Dart_NativeArguments args) {
42 int64_t id = 0; 47 int64_t id = 0;
43 bool ok = DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &id); 48 bool ok = DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &id);
44 ASSERT(ok); 49 ASSERT(ok);
45 USE(ok); 50 USE(ok);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 intptr_t socket = Socket::CreateConnect(addr, port); 115 intptr_t socket = Socket::CreateConnect(addr, port);
111 OSError error; 116 OSError error;
112 if (socket >= 0) { 117 if (socket >= 0) {
113 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket); 118 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
114 Dart_SetReturnValue(args, Dart_True()); 119 Dart_SetReturnValue(args, Dart_True());
115 } else { 120 } else {
116 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error)); 121 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
117 } 122 }
118 } 123 }
119 124
125 void FUNCTION_NAME(Socket_CreateBindDatagram)(Dart_NativeArguments args) {
126 RawAddr addr;
127 GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
128 int64_t port = DartUtils::GetInt64ValueCheckRange(
129 Dart_GetNativeArgument(args, 2),
130 0,
131 65535);
132 intptr_t socket = Socket::CreateBindDatagram(
133 &addr,
134 port,
135 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
136 OSError error;
Anders Johnsen 2013/11/29 12:36:54 Unused?
Søren Gjesse 2013/12/12 11:38:46 Yes, removed.
137 if (socket >= 0) {
138 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
139 Dart_SetReturnValue(args, Dart_True());
140 } else {
141 OSError error;
142 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
143 }
144 }
145
120 146
121 void FUNCTION_NAME(Socket_Available)(Dart_NativeArguments args) { 147 void FUNCTION_NAME(Socket_Available)(Dart_NativeArguments args) {
122 intptr_t socket = 148 intptr_t socket =
123 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); 149 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
124 intptr_t available = Socket::Available(socket); 150 intptr_t available = Socket::Available(socket);
125 if (available >= 0) { 151 if (available >= 0) {
126 Dart_SetReturnValue(args, Dart_NewInteger(available)); 152 Dart_SetReturnValue(args, Dart_NewInteger(available));
127 } else { 153 } else {
128 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 154 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
129 } 155 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 Dart_SetReturnValue(args, err); 201 Dart_SetReturnValue(args, err);
176 } 202 }
177 } else if (available == 0) { 203 } else if (available == 0) {
178 Dart_SetReturnValue(args, Dart_Null()); 204 Dart_SetReturnValue(args, Dart_Null());
179 } else { 205 } else {
180 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 206 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
181 } 207 }
182 } 208 }
183 209
184 210
211 void FUNCTION_NAME(Socket_RecvFrom)(Dart_NativeArguments args) {
212 static bool drop_datagrams = Dart_IsVMFlagSet("drop_datagrams");
213 intptr_t socket =
214 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
215
216 // TODO(sgjesse): This needs to be 64k as that is the max UDP packet size.
217 uint8_t buffer[4096];
218 RawAddr addr;
219 intptr_t bytes_read = Socket::RecvFrom(socket, buffer, 4096, &addr);
220 Dart_Handle err;
221 if (bytes_read > 0) {
222 uint8_t* data_buffer = NULL;
223 Dart_Handle data = IOBuffer::Allocate(bytes_read, &data_buffer);
224 if (Dart_IsError(data)) Dart_PropagateError(data);
225 ASSERT(data_buffer != NULL);
226 memmove(data_buffer, buffer, bytes_read);
227
228 // Get the port and clear it in the sockaddr structure.
229 int port = SocketAddress::GetAddrPort(&addr);
230 if (addr.addr.sa_family == AF_INET) {
231 addr.in.sin_port = 0;
232 } else {
233 ASSERT(addr.addr.sa_family == AF_INET6);
234 addr.in6.sin6_port = 0;
235 }
236 // Format the address to a string using the numeric format.
237 char numeric_address[INET6_ADDRSTRLEN];
238 Socket::FormatNumericAddress(&addr, numeric_address, INET6_ADDRSTRLEN);
239
240 // Create a Datagram object with the data and sender address and port.
241 const int kNumArgs = 5;
242 Dart_Handle dart_args[kNumArgs];
243 dart_args[0] = data;
244 dart_args[1] = Dart_NewBoolean(addr.addr.sa_family == AF_INET6);
245 dart_args[2] = Dart_NewStringFromCString(numeric_address);
246 if (Dart_IsError(dart_args[2])) Dart_PropagateError(dart_args[2]);
247 int len = SocketAddress::GetAddrLength(&addr);
248 dart_args[3] = Dart_NewTypedData(Dart_TypedData_kUint8, len);
249 if (Dart_IsError(dart_args[3])) Dart_PropagateError(dart_args[3]);
250 err = Dart_ListSetAsBytes(
251 dart_args[3], 0, reinterpret_cast<uint8_t *>(&addr), len);
252 if (Dart_IsError(err)) Dart_PropagateError(err);
253 dart_args[4] = Dart_NewInteger(port);
254 if (Dart_IsError(dart_args[4])) Dart_PropagateError(dart_args[4]);
255 // TODO(sgjesse): Cache the _makeDatagram function somewhere.
256 Dart_Handle io_lib =
257 Dart_LookupLibrary(DartUtils::NewString("dart:io"));
258 if (Dart_IsError(io_lib)) Dart_PropagateError(io_lib);
259 Dart_Handle result =
260 Dart_Invoke(io_lib,
261 DartUtils::NewString("_makeDatagram"),
262 kNumArgs,
263 dart_args);
264 if (Dart_IsError(result)) Dart_PropagateError(result);
265 if (drop_datagrams) {
Anders Johnsen 2013/11/29 12:36:54 Drop earlier?
Søren Gjesse 2013/12/12 11:38:46 Done.
266 int random = rand_r(&rand_r_state);
267 if (random > (RAND_MAX / 2)) {
268 Dart_SetReturnValue(args, result);
269 } else {
270 Dart_SetReturnValue(args, Dart_Null());
271 }
272 } else {
273 Dart_SetReturnValue(args, result);
274 }
275 } else if (bytes_read == 0) {
276 Dart_SetReturnValue(args, Dart_Null());
277 } else {
278 ASSERT(bytes_read == -1);
279 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
280 }
281 }
282
283
185 void FUNCTION_NAME(Socket_WriteList)(Dart_NativeArguments args) { 284 void FUNCTION_NAME(Socket_WriteList)(Dart_NativeArguments args) {
186 static bool short_socket_writes = Dart_IsVMFlagSet("short_socket_write"); 285 static bool short_socket_writes = Dart_IsVMFlagSet("short_socket_write");
187 intptr_t socket = 286 intptr_t socket =
188 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); 287 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
189 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1); 288 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
190 ASSERT(Dart_IsList(buffer_obj)); 289 ASSERT(Dart_IsList(buffer_obj));
191 intptr_t offset = 290 intptr_t offset =
192 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2)); 291 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
193 intptr_t length = 292 intptr_t length =
194 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3)); 293 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
(...skipping 14 matching lines...) Expand all
209 Dart_SetReturnValue(args, Dart_NewInteger(bytes_written)); 308 Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
210 } else { 309 } else {
211 // Extract OSError before we release data, as it may override the error. 310 // Extract OSError before we release data, as it may override the error.
212 OSError os_error; 311 OSError os_error;
213 Dart_TypedDataReleaseData(buffer_obj); 312 Dart_TypedDataReleaseData(buffer_obj);
214 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error)); 313 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
215 } 314 }
216 } 315 }
217 316
218 317
318 void FUNCTION_NAME(Socket_SendTo)(Dart_NativeArguments args) {
319 intptr_t socket =
320 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
321 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
322 intptr_t offset =
323 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
324 intptr_t length =
325 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
326 Dart_Handle address_obj = Dart_GetNativeArgument(args, 4);
327 ASSERT(Dart_IsList(address_obj));
328 RawAddr addr;
329 GetSockAddr(address_obj, &addr);
330 int64_t port = DartUtils::GetInt64ValueCheckRange(
331 Dart_GetNativeArgument(args, 5),
332 0,
333 65535);
334 SocketAddress::SetAddrPort(&addr, port);
335 Dart_TypedData_Type type;
336 uint8_t* buffer = NULL;
337 intptr_t len;
338 Dart_Handle result = Dart_TypedDataAcquireData(
339 buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len);
340 if (Dart_IsError(result)) Dart_PropagateError(result);
341 ASSERT((offset + length) <= len);
342 buffer += offset;
343 intptr_t bytes_written = Socket::SendTo(socket, buffer, length, addr);
344 if (bytes_written >= 0) {
345 Dart_TypedDataReleaseData(buffer_obj);
346 Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
347 } else {
348 // Extract OSError before we release data, as it may override the error.
349 OSError os_error;
350 Dart_TypedDataReleaseData(buffer_obj);
351 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
352 }
353 }
354
355
219 void FUNCTION_NAME(Socket_GetPort)(Dart_NativeArguments args) { 356 void FUNCTION_NAME(Socket_GetPort)(Dart_NativeArguments args) {
220 intptr_t socket = 357 intptr_t socket =
221 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); 358 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
222 OSError os_error; 359 OSError os_error;
223 intptr_t port = Socket::GetPort(socket); 360 intptr_t port = Socket::GetPort(socket);
224 if (port > 0) { 361 if (port > 0) {
225 Dart_SetReturnValue(args, Dart_NewInteger(port)); 362 Dart_SetReturnValue(args, Dart_NewInteger(port));
226 } else { 363 } else {
227 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 364 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
228 } 365 }
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 } else { 593 } else {
457 result = CObject::NewOSError(os_error); 594 result = CObject::NewOSError(os_error);
458 delete os_error; 595 delete os_error;
459 } 596 }
460 return result; 597 return result;
461 } 598 }
462 return CObject::IllegalArgumentError(); 599 return CObject::IllegalArgumentError();
463 } 600 }
464 601
465 602
603 void FUNCTION_NAME(Socket_GetOption)(Dart_NativeArguments args) {
604 intptr_t socket =
605 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
606 int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
607 intptr_t protocol =
608 static_cast<intptr_t>(
609 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2)));
610 bool ok;
611 switch (option) {
612 case 0: { // TCP_NODELAY.
613 bool enabled;
614 ok = Socket::GetNoDelay(socket, &enabled);
615 if (ok) {
616 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
617 }
618 break;
619 }
620 case 1: { // IP_MULTICAST_LOOP.
621 bool enabled;
622 ok = Socket::GetMulticastLoop(socket, protocol, &enabled);
623 if (ok) {
624 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
625 }
626 break;
627 }
628 case 2: { // IP_MULTICAST_TTL.
629 int value;
630 ok = Socket::GetMulticastHops(socket, protocol, &value);
631 if (ok) {
632 Dart_SetReturnValue(args, Dart_NewInteger(value));
633 }
634 break;
635 }
636 case 3: { // IP_MULTICAST_IF.
637 UNIMPLEMENTED();
638 break;
639 }
640 case 4: { // IP_BROADCAST.
641 bool enabled;
642 ok = Socket::GetBroadcast(socket, &enabled);
643 if (ok) {
644 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
645 }
646 break;
647 }
648 default:
649 UNREACHABLE();
650 break;
651 }
652 // In case of failure the return value is not set above.
653 if (!ok) {
654 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
655 }
656 }
657
658
466 void FUNCTION_NAME(Socket_SetOption)(Dart_NativeArguments args) { 659 void FUNCTION_NAME(Socket_SetOption)(Dart_NativeArguments args) {
467 bool result = false; 660 bool result = false;
468 intptr_t socket = 661 intptr_t socket =
469 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); 662 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
470 Dart_Handle option_obj = Dart_GetNativeArgument(args, 1); 663 int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
471 int64_t option; 664 int64_t protocol = DartUtils::GetInt64ValueCheckRange(
472 Dart_Handle err = Dart_IntegerToInt64(option_obj, &option); 665 Dart_GetNativeArgument(args, 2),
473 if (Dart_IsError(err)) Dart_PropagateError(err); 666 SocketAddress::TYPE_IPV4,
474 Dart_Handle enabled_obj = Dart_GetNativeArgument(args, 2); 667 SocketAddress::TYPE_IPV6);
475 bool enabled;
476 err = Dart_BooleanValue(enabled_obj, &enabled);
477 if (Dart_IsError(err)) Dart_PropagateError(err);
478 switch (option) { 668 switch (option) {
479 case 0: // TCP_NODELAY. 669 case 0: // TCP_NODELAY.
480 result = Socket::SetNoDelay(socket, enabled); 670 result = Socket::SetNoDelay(
671 socket, DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
672 break;
673 case 1: // IP_MULTICAST_LOOP.
674 result = Socket::SetMulticastLoop(
675 socket,
676 protocol,
677 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
678 break;
679 case 2: // IP_MULTICAST_TTL.
680 result = Socket::SetMulticastHops(
681 socket,
682 protocol,
683 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3)));
684 break;
685 case 3: { // IP_MULTICAST_IF.
686 UNIMPLEMENTED();
687 break;
688 }
689 case 4: // IP_BROADCAST.
690 result = Socket::SetBroadcast(
691 socket, DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
481 break; 692 break;
482 default: 693 default:
694 Dart_PropagateError(Dart_NewApiError("Value outside expected range"));
483 break; 695 break;
484 } 696 }
485 Dart_SetReturnValue(args, Dart_NewBoolean(result)); 697 if (result) {
698 Dart_SetReturnValue(args, Dart_Null());
699 } else {
700 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
701 }
486 } 702 }
487 703
488 704
705 void FUNCTION_NAME(Socket_JoinMulticast)(Dart_NativeArguments args) {
706 intptr_t socket =
707 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
708 RawAddr addr;
709 GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
710 if (Socket::JoinMulticast(socket, &addr, 0)) {
711 Dart_SetReturnValue(args, Dart_Null());
712 } else {
713 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
714 }
715 }
716
717
718 void FUNCTION_NAME(Socket_LeaveMulticast)(Dart_NativeArguments args) {
719 intptr_t socket =
720 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
721 RawAddr addr;
722 GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
723 if (Socket::LeaveMulticast(socket, &addr, 0)) {
724 Dart_SetReturnValue(args, Dart_Null());
725 } else {
726 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
727 }
728 }
729
730
489 void Socket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) { 731 void Socket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) {
490 Dart_Handle err = 732 Dart_Handle err =
491 Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id); 733 Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id);
492 if (Dart_IsError(err)) Dart_PropagateError(err); 734 if (Dart_IsError(err)) Dart_PropagateError(err);
493 } 735 }
494 736
495 737
496 intptr_t Socket::GetSocketIdNativeField(Dart_Handle socket_obj) { 738 intptr_t Socket::GetSocketIdNativeField(Dart_Handle socket_obj) {
497 intptr_t socket = 0; 739 intptr_t socket = 0;
498 Dart_Handle err = 740 Dart_Handle err =
499 Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &socket); 741 Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &socket);
500 if (Dart_IsError(err)) Dart_PropagateError(err); 742 if (Dart_IsError(err)) Dart_PropagateError(err);
501 return socket; 743 return socket;
502 } 744 }
503 745
504 } // namespace bin 746 } // namespace bin
505 } // namespace dart 747 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698