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

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

Issue 2780063002: Pulled a significant portion of Socket implementation into BaseSocket in order to prepare for the s… (Closed)
Patch Set: Updated copyright date, fixed incorrect items in socket_common_macos.h 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
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 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "bin/socket.h" 7 #include "bin/socket.h"
8 8
9 #include "bin/dartutils.h" 9 #include "bin/dartutils.h"
10 #include "bin/io_buffer.h" 10 #include "bin/io_buffer.h"
11 #include "bin/isolate_data.h" 11 #include "bin/isolate_data.h"
12 #include "bin/lockers.h" 12 #include "bin/lockers.h"
13 #include "bin/thread.h" 13 #include "bin/thread.h"
14 #include "bin/utils.h" 14 #include "bin/utils.h"
15 15
16 #include "include/dart_api.h" 16 #include "include/dart_api.h"
17 17
18 #include "platform/globals.h" 18 #include "platform/globals.h"
19 #include "platform/utils.h" 19 #include "platform/utils.h"
20 20
21 namespace dart { 21 namespace dart {
22 namespace bin { 22 namespace bin {
23 23
24 static const int kSocketIdNativeField = 0;
25
26 ListeningSocketRegistry* globalTcpListeningSocketRegistry = NULL; 24 ListeningSocketRegistry* globalTcpListeningSocketRegistry = NULL;
27 25
28 bool short_socket_read = false;
29
30 bool short_socket_write = false;
31
32 void ListeningSocketRegistry::Initialize() { 26 void ListeningSocketRegistry::Initialize() {
33 ASSERT(globalTcpListeningSocketRegistry == NULL); 27 ASSERT(globalTcpListeningSocketRegistry == NULL);
34 globalTcpListeningSocketRegistry = new ListeningSocketRegistry(); 28 globalTcpListeningSocketRegistry = new ListeningSocketRegistry();
35 } 29 }
36 30
37 31
38 ListeningSocketRegistry* ListeningSocketRegistry::Instance() { 32 ListeningSocketRegistry* ListeningSocketRegistry::Instance() {
39 return globalTcpListeningSocketRegistry; 33 return globalTcpListeningSocketRegistry;
40 } 34 }
41 35
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 return DartUtils::NewDartOSError(&os_error); 126 return DartUtils::NewDartOSError(&os_error);
133 } 127 }
134 128
135 // This socket creation is the exact same as the one which originally 129 // This socket creation is the exact same as the one which originally
136 // created the socket. We therefore increment the refcount and reuse 130 // created the socket. We therefore increment the refcount and reuse
137 // the file descriptor. 131 // the file descriptor.
138 os_socket->ref_count++; 132 os_socket->ref_count++;
139 133
140 // We set as a side-effect the file descriptor on the dart 134 // We set as a side-effect the file descriptor on the dart
141 // socket_object. 135 // socket_object.
142 Socket::SetSocketIdNativeField(socket_object, os_socket->socketfd); 136 BaseSocket::SetSocketIdNativeField(socket_object, os_socket->socketfd);
143 137
144 return Dart_True(); 138 return Dart_True();
145 } 139 }
146 } 140 }
147 } 141 }
148 142
149 // There is no socket listening on that (address, port), so we create new one. 143 // There is no socket listening on that (address, port), so we create new one.
150 intptr_t socketfd = ServerSocket::CreateBindListen(addr, backlog, v6_only); 144 intptr_t socketfd = ServerSocket::CreateBindListen(addr, backlog, v6_only);
151 if (socketfd == -5) { 145 if (socketfd == -5) {
152 OSError os_error(-1, "Invalid host", OSError::kUnknown); 146 OSError os_error(-1, "Invalid host", OSError::kUnknown);
153 return DartUtils::NewDartOSError(&os_error); 147 return DartUtils::NewDartOSError(&os_error);
154 } 148 }
155 if (socketfd < 0) { 149 if (socketfd < 0) {
156 OSError error; 150 OSError error;
157 return DartUtils::NewDartOSError(&error); 151 return DartUtils::NewDartOSError(&error);
158 } 152 }
159 if (!ServerSocket::StartAccept(socketfd)) { 153 if (!ServerSocket::StartAccept(socketfd)) {
160 OSError os_error(-1, "Failed to start accept", OSError::kUnknown); 154 OSError os_error(-1, "Failed to start accept", OSError::kUnknown);
161 return DartUtils::NewDartOSError(&os_error); 155 return DartUtils::NewDartOSError(&os_error);
162 } 156 }
163 intptr_t allocated_port = Socket::GetPort(socketfd); 157 intptr_t allocated_port = BaseSocket::GetPort(socketfd);
164 ASSERT(allocated_port > 0); 158 ASSERT(allocated_port > 0);
165 159
166 if (allocated_port != port) { 160 if (allocated_port != port) {
167 // There are two cases to consider: 161 // There are two cases to consider:
168 // 162 //
169 // a) The user requested (address, port) where port != 0 which means 163 // a) The user requested (address, port) where port != 0 which means
170 // we re-use an existing socket if available (and it is shared) or we 164 // we re-use an existing socket if available (and it is shared) or we
171 // create a new one. The new socket is guaranteed to have that 165 // create a new one. The new socket is guaranteed to have that
172 // selected port. 166 // selected port.
173 // 167 //
174 // b) The user requested (address, 0). This will make us *always* create a 168 // b) The user requested (address, 0). This will make us *always* create a
175 // new socket. The OS will assign it a new `allocated_port` and we will 169 // new socket. The OS will assign it a new `allocated_port` and we will
176 // insert into our data structures. *BUT* There might already be an 170 // insert into our data structures. *BUT* There might already be an
177 // existing (address2, `allocated_port`) where address != address2. So 171 // existing (address2, `allocated_port`) where address != address2. So
178 // we need to do another `LookupByPort(allocated_port)` and link them 172 // we need to do another `LookupByPort(allocated_port)` and link them
179 // via `OSSocket->next`. 173 // via `OSSocket->next`.
180 ASSERT(port == 0); 174 ASSERT(port == 0);
181 first_os_socket = LookupByPort(allocated_port); 175 first_os_socket = LookupByPort(allocated_port);
182 } 176 }
183 177
184 OSSocket* os_socket = 178 OSSocket* os_socket =
185 new OSSocket(addr, allocated_port, v6_only, shared, socketfd); 179 new OSSocket(addr, allocated_port, v6_only, shared, socketfd);
186 os_socket->ref_count = 1; 180 os_socket->ref_count = 1;
187 os_socket->next = first_os_socket; 181 os_socket->next = first_os_socket;
188 182
189 InsertByPort(allocated_port, os_socket); 183 InsertByPort(allocated_port, os_socket);
190 InsertByFd(socketfd, os_socket); 184 InsertByFd(socketfd, os_socket);
191 185
192 // We set as a side-effect the port on the dart socket_object. 186 // We set as a side-effect the port on the dart socket_object.
193 Socket::SetSocketIdNativeField(socket_object, socketfd); 187 BaseSocket::SetSocketIdNativeField(socket_object, socketfd);
194 188
195 return Dart_True(); 189 return Dart_True();
196 } 190 }
197 191
198 192
199 bool ListeningSocketRegistry::CloseOneSafe(OSSocket* os_socket, 193 bool ListeningSocketRegistry::CloseOneSafe(OSSocket* os_socket,
200 bool update_hash_maps) { 194 bool update_hash_maps) {
201 ASSERT(!mutex_->TryLock()); 195 ASSERT(!mutex_->TryLock());
202 ASSERT(os_socket != NULL); 196 ASSERT(os_socket != NULL);
203 ASSERT(os_socket->ref_count > 0); 197 ASSERT(os_socket->ref_count > 0);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 return CloseOneSafe(os_socket, true); 246 return CloseOneSafe(os_socket, true);
253 } else { 247 } else {
254 // It should be impossible for the event handler to close something that 248 // It should be impossible for the event handler to close something that
255 // hasn't been created before. 249 // hasn't been created before.
256 UNREACHABLE(); 250 UNREACHABLE();
257 return false; 251 return false;
258 } 252 }
259 } 253 }
260 254
261 255
262 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
263 const char* address =
264 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
265 ASSERT(address != NULL);
266 RawAddr raw;
267 memset(&raw, 0, sizeof(raw));
268 int type = strchr(address, ':') == NULL ? SocketAddress::TYPE_IPV4
269 : SocketAddress::TYPE_IPV6;
270 if (type == SocketAddress::TYPE_IPV4) {
271 raw.addr.sa_family = AF_INET;
272 } else {
273 raw.addr.sa_family = AF_INET6;
274 }
275 bool ok = Socket::ParseAddress(type, address, &raw);
276 if (!ok) {
277 Dart_SetReturnValue(args, Dart_Null());
278 } else {
279 Dart_SetReturnValue(args, SocketAddress::ToTypedData(raw));
280 }
281 }
282
283
284 void FUNCTION_NAME(NetworkInterface_ListSupported)(Dart_NativeArguments args) {
285 Dart_SetReturnValue(args, Dart_NewBoolean(Socket::ListInterfacesSupported()));
286 }
287
288
289 void FUNCTION_NAME(Socket_CreateConnect)(Dart_NativeArguments args) { 256 void FUNCTION_NAME(Socket_CreateConnect)(Dart_NativeArguments args) {
290 RawAddr addr; 257 RawAddr addr;
291 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr); 258 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
292 Dart_Handle port_arg = Dart_GetNativeArgument(args, 2); 259 Dart_Handle port_arg = Dart_GetNativeArgument(args, 2);
293 int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535); 260 int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
294 SocketAddress::SetAddrPort(&addr, static_cast<intptr_t>(port)); 261 SocketAddress::SetAddrPort(&addr, static_cast<intptr_t>(port));
295 intptr_t socket = Socket::CreateConnect(addr); 262 intptr_t socket = Socket::CreateConnect(addr);
296 OSError error; 263 OSError error;
297 if (socket >= 0) { 264 if (socket >= 0) {
298 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket); 265 BaseSocket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
299 Dart_SetReturnValue(args, Dart_True()); 266 Dart_SetReturnValue(args, Dart_True());
300 } else { 267 } else {
301 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error)); 268 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
302 } 269 }
303 } 270 }
304 271
305 272
306 void FUNCTION_NAME(Socket_CreateBindConnect)(Dart_NativeArguments args) { 273 void FUNCTION_NAME(Socket_CreateBindConnect)(Dart_NativeArguments args) {
307 RawAddr addr; 274 RawAddr addr;
308 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr); 275 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
309 Dart_Handle port_arg = Dart_GetNativeArgument(args, 2); 276 Dart_Handle port_arg = Dart_GetNativeArgument(args, 2);
310 int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535); 277 int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
311 SocketAddress::SetAddrPort(&addr, static_cast<intptr_t>(port)); 278 SocketAddress::SetAddrPort(&addr, static_cast<intptr_t>(port));
312 RawAddr sourceAddr; 279 RawAddr sourceAddr;
313 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 3), &sourceAddr); 280 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 3), &sourceAddr);
314 intptr_t socket = Socket::CreateBindConnect(addr, sourceAddr); 281 intptr_t socket = Socket::CreateBindConnect(addr, sourceAddr);
315 OSError error; 282 OSError error;
316 if (socket >= 0) { 283 if (socket >= 0) {
317 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket); 284 BaseSocket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
318 Dart_SetReturnValue(args, Dart_True()); 285 Dart_SetReturnValue(args, Dart_True());
319 } else { 286 } else {
320 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error)); 287 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
321 } 288 }
322 } 289 }
323 290
324 void FUNCTION_NAME(Socket_IsBindError)(Dart_NativeArguments args) {
325 intptr_t error_number =
326 DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
327 bool is_bind_error = Socket::IsBindError(error_number);
328 Dart_SetReturnValue(args, is_bind_error ? Dart_True() : Dart_False());
329 }
330 291
331 void FUNCTION_NAME(Socket_CreateBindDatagram)(Dart_NativeArguments args) { 292 void FUNCTION_NAME(Socket_CreateBindDatagram)(Dart_NativeArguments args) {
332 RawAddr addr; 293 RawAddr addr;
333 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr); 294 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
334 Dart_Handle port_arg = Dart_GetNativeArgument(args, 2); 295 Dart_Handle port_arg = Dart_GetNativeArgument(args, 2);
335 int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535); 296 int64_t port = DartUtils::GetInt64ValueCheckRange(port_arg, 0, 65535);
336 SocketAddress::SetAddrPort(&addr, port); 297 SocketAddress::SetAddrPort(&addr, port);
337 bool reuse_addr = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); 298 bool reuse_addr = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3));
338 intptr_t socket = Socket::CreateBindDatagram(addr, reuse_addr); 299 intptr_t socket = Socket::CreateBindDatagram(addr, reuse_addr);
339 if (socket >= 0) { 300 if (socket >= 0) {
340 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket); 301 BaseSocket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
341 Dart_SetReturnValue(args, Dart_True()); 302 Dart_SetReturnValue(args, Dart_True());
342 } else { 303 } else {
343 OSError error; 304 OSError error;
344 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error)); 305 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
345 } 306 }
346 } 307 }
347 308
348 309
349 void FUNCTION_NAME(Socket_Available)(Dart_NativeArguments args) {
350 intptr_t socket =
351 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
352 intptr_t available = Socket::Available(socket);
353 if (available >= 0) {
354 Dart_SetReturnValue(args, Dart_NewInteger(available));
355 } else {
356 // Available failed. Mark socket as having data, to trigger a future read
357 // event where the actual error can be reported.
358 Dart_SetReturnValue(args, Dart_NewInteger(1));
359 }
360 }
361
362
363 void FUNCTION_NAME(Socket_Read)(Dart_NativeArguments args) {
364 intptr_t socket =
365 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
366 int64_t length = 0;
367 if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) {
368 if (short_socket_read) {
369 length = (length + 1) / 2;
370 }
371 uint8_t* buffer = NULL;
372 Dart_Handle result = IOBuffer::Allocate(length, &buffer);
373 if (Dart_IsError(result)) {
374 Dart_PropagateError(result);
375 }
376 ASSERT(buffer != NULL);
377 intptr_t bytes_read = Socket::Read(socket, buffer, length);
378 if (bytes_read == length) {
379 Dart_SetReturnValue(args, result);
380 } else if (bytes_read > 0) {
381 uint8_t* new_buffer = NULL;
382 Dart_Handle new_result = IOBuffer::Allocate(bytes_read, &new_buffer);
383 if (Dart_IsError(new_result)) {
384 Dart_PropagateError(new_result);
385 }
386 ASSERT(new_buffer != NULL);
387 memmove(new_buffer, buffer, bytes_read);
388 Dart_SetReturnValue(args, new_result);
389 } else if (bytes_read == 0) {
390 // On MacOS when reading from a tty Ctrl-D will result in reading one
391 // less byte then reported as available.
392 Dart_SetReturnValue(args, Dart_Null());
393 } else {
394 ASSERT(bytes_read == -1);
395 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
396 }
397 } else {
398 OSError os_error(-1, "Invalid argument", OSError::kUnknown);
399 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
400 }
401 }
402
403
404 void FUNCTION_NAME(Socket_RecvFrom)(Dart_NativeArguments args) {
405 intptr_t socket =
406 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
407
408 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can
409 // handle 64k datagrams.
410 IsolateData* isolate_data =
411 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
412 if (isolate_data->udp_receive_buffer == NULL) {
413 isolate_data->udp_receive_buffer =
414 reinterpret_cast<uint8_t*>(malloc(65536));
415 }
416 RawAddr addr;
417 intptr_t bytes_read =
418 Socket::RecvFrom(socket, isolate_data->udp_receive_buffer, 65536, &addr);
419 if (bytes_read == 0) {
420 Dart_SetReturnValue(args, Dart_Null());
421 return;
422 }
423 if (bytes_read < 0) {
424 ASSERT(bytes_read == -1);
425 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
426 return;
427 }
428 // Datagram data read. Copy into buffer of the exact size,
429 ASSERT(bytes_read > 0);
430 uint8_t* data_buffer = NULL;
431 Dart_Handle data = IOBuffer::Allocate(bytes_read, &data_buffer);
432 if (Dart_IsError(data)) {
433 Dart_PropagateError(data);
434 }
435 ASSERT(data_buffer != NULL);
436 memmove(data_buffer, isolate_data->udp_receive_buffer, bytes_read);
437
438 // Get the port and clear it in the sockaddr structure.
439 int port = SocketAddress::GetAddrPort(addr);
440 if (addr.addr.sa_family == AF_INET) {
441 addr.in.sin_port = 0;
442 } else {
443 ASSERT(addr.addr.sa_family == AF_INET6);
444 addr.in6.sin6_port = 0;
445 }
446 // Format the address to a string using the numeric format.
447 char numeric_address[INET6_ADDRSTRLEN];
448 Socket::FormatNumericAddress(addr, numeric_address, INET6_ADDRSTRLEN);
449
450 // Create a Datagram object with the data and sender address and port.
451 const int kNumArgs = 4;
452 Dart_Handle dart_args[kNumArgs];
453 dart_args[0] = data;
454 dart_args[1] = Dart_NewStringFromCString(numeric_address);
455 if (Dart_IsError(dart_args[1])) {
456 Dart_PropagateError(dart_args[1]);
457 }
458 dart_args[2] = SocketAddress::ToTypedData(addr);
459 dart_args[3] = Dart_NewInteger(port);
460 if (Dart_IsError(dart_args[3])) {
461 Dart_PropagateError(dart_args[3]);
462 }
463 // TODO(sgjesse): Cache the _makeDatagram function somewhere.
464 Dart_Handle io_lib = Dart_LookupLibrary(DartUtils::NewString("dart:io"));
465 if (Dart_IsError(io_lib)) {
466 Dart_PropagateError(io_lib);
467 }
468 Dart_Handle result = Dart_Invoke(
469 io_lib, DartUtils::NewString("_makeDatagram"), kNumArgs, dart_args);
470 Dart_SetReturnValue(args, result);
471 }
472
473
474 void FUNCTION_NAME(Socket_WriteList)(Dart_NativeArguments args) {
475 intptr_t socket =
476 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
477 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
478 ASSERT(Dart_IsList(buffer_obj));
479 intptr_t offset = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
480 intptr_t length = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
481 bool short_write = false;
482 if (short_socket_write) {
483 if (length > 1) {
484 short_write = true;
485 }
486 length = (length + 1) / 2;
487 }
488 Dart_TypedData_Type type;
489 uint8_t* buffer = NULL;
490 intptr_t len;
491 Dart_Handle result = Dart_TypedDataAcquireData(
492 buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len);
493 if (Dart_IsError(result)) {
494 Dart_PropagateError(result);
495 }
496 ASSERT((offset + length) <= len);
497 buffer += offset;
498 intptr_t bytes_written = Socket::Write(socket, buffer, length);
499 if (bytes_written >= 0) {
500 Dart_TypedDataReleaseData(buffer_obj);
501 if (short_write) {
502 // If the write was forced 'short', indicate by returning the negative
503 // number of bytes. A forced short write may not trigger a write event.
504 Dart_SetReturnValue(args, Dart_NewInteger(-bytes_written));
505 } else {
506 Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
507 }
508 } else {
509 // Extract OSError before we release data, as it may override the error.
510 OSError os_error;
511 Dart_TypedDataReleaseData(buffer_obj);
512 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
513 }
514 }
515
516
517 void FUNCTION_NAME(Socket_SendTo)(Dart_NativeArguments args) {
518 intptr_t socket =
519 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
520 Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
521 intptr_t offset = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
522 intptr_t length = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
523 Dart_Handle address_obj = Dart_GetNativeArgument(args, 4);
524 ASSERT(Dart_IsList(address_obj));
525 RawAddr addr;
526 SocketAddress::GetSockAddr(address_obj, &addr);
527 int64_t port = DartUtils::GetInt64ValueCheckRange(
528 Dart_GetNativeArgument(args, 5), 0, 65535);
529 SocketAddress::SetAddrPort(&addr, port);
530 Dart_TypedData_Type type;
531 uint8_t* buffer = NULL;
532 intptr_t len;
533 Dart_Handle result = Dart_TypedDataAcquireData(
534 buffer_obj, &type, reinterpret_cast<void**>(&buffer), &len);
535 if (Dart_IsError(result)) {
536 Dart_PropagateError(result);
537 }
538 ASSERT((offset + length) <= len);
539 buffer += offset;
540 intptr_t bytes_written = Socket::SendTo(socket, buffer, length, addr);
541 if (bytes_written >= 0) {
542 Dart_TypedDataReleaseData(buffer_obj);
543 Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
544 } else {
545 // Extract OSError before we release data, as it may override the error.
546 OSError os_error;
547 Dart_TypedDataReleaseData(buffer_obj);
548 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
549 }
550 }
551
552
553 void FUNCTION_NAME(Socket_GetPort)(Dart_NativeArguments args) {
554 intptr_t socket =
555 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
556 OSError os_error;
557 intptr_t port = Socket::GetPort(socket);
558 if (port > 0) {
559 Dart_SetReturnValue(args, Dart_NewInteger(port));
560 } else {
561 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
562 }
563 }
564
565
566 void FUNCTION_NAME(Socket_GetRemotePeer)(Dart_NativeArguments args) {
567 intptr_t socket =
568 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
569 OSError os_error;
570 intptr_t port = 0;
571 SocketAddress* addr = Socket::GetRemotePeer(socket, &port);
572 if (addr != NULL) {
573 Dart_Handle list = Dart_NewList(2);
574
575 Dart_Handle entry = Dart_NewList(3);
576 Dart_ListSetAt(entry, 0, Dart_NewInteger(addr->GetType()));
577 Dart_ListSetAt(entry, 1, Dart_NewStringFromCString(addr->as_string()));
578
579 RawAddr raw = addr->addr();
580 Dart_ListSetAt(entry, 2, SocketAddress::ToTypedData(raw));
581
582 Dart_ListSetAt(list, 0, entry);
583 Dart_ListSetAt(list, 1, Dart_NewInteger(port));
584 Dart_SetReturnValue(args, list);
585 delete addr;
586 } else {
587 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
588 }
589 }
590
591
592 void FUNCTION_NAME(Socket_GetError)(Dart_NativeArguments args) {
593 intptr_t socket =
594 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
595 OSError os_error;
596 Socket::GetError(socket, &os_error);
597 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
598 }
599
600
601 void FUNCTION_NAME(Socket_GetType)(Dart_NativeArguments args) {
602 intptr_t socket =
603 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
604 OSError os_error;
605 intptr_t type = Socket::GetType(socket);
606 if (type >= 0) {
607 Dart_SetReturnValue(args, Dart_NewInteger(type));
608 } else {
609 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
610 }
611 }
612
613
614 void FUNCTION_NAME(Socket_GetStdioHandle)(Dart_NativeArguments args) {
615 int64_t num =
616 DartUtils::GetInt64ValueCheckRange(Dart_GetNativeArgument(args, 1), 0, 2);
617 intptr_t socket = Socket::GetStdioHandle(num);
618 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
619 Dart_SetReturnValue(args, Dart_NewBoolean(socket >= 0));
620 }
621
622
623 void FUNCTION_NAME(Socket_GetSocketId)(Dart_NativeArguments args) {
624 intptr_t id = Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
625 Dart_SetReturnValue(args, Dart_NewInteger(id));
626 }
627
628
629 void FUNCTION_NAME(Socket_SetSocketId)(Dart_NativeArguments args) {
630 intptr_t id = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
631 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), id);
632 }
633
634
635 void FUNCTION_NAME(ServerSocket_CreateBindListen)(Dart_NativeArguments args) { 310 void FUNCTION_NAME(ServerSocket_CreateBindListen)(Dart_NativeArguments args) {
636 RawAddr addr; 311 RawAddr addr;
637 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr); 312 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
638 int64_t port = DartUtils::GetInt64ValueCheckRange( 313 int64_t port = DartUtils::GetInt64ValueCheckRange(
639 Dart_GetNativeArgument(args, 2), 0, 65535); 314 Dart_GetNativeArgument(args, 2), 0, 65535);
640 SocketAddress::SetAddrPort(&addr, port); 315 SocketAddress::SetAddrPort(&addr, port);
641 int64_t backlog = DartUtils::GetInt64ValueCheckRange( 316 int64_t backlog = DartUtils::GetInt64ValueCheckRange(
642 Dart_GetNativeArgument(args, 3), 0, 65535); 317 Dart_GetNativeArgument(args, 3), 0, 65535);
643 bool v6_only = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); 318 bool v6_only = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
644 bool shared = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); 319 bool shared = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5));
645 320
646 Dart_Handle socket_object = Dart_GetNativeArgument(args, 0); 321 Dart_Handle socket_object = Dart_GetNativeArgument(args, 0);
647 Dart_Handle result = ListeningSocketRegistry::Instance()->CreateBindListen( 322 Dart_Handle result = ListeningSocketRegistry::Instance()->CreateBindListen(
648 socket_object, addr, backlog, v6_only, shared); 323 socket_object, addr, backlog, v6_only, shared);
649 Dart_SetReturnValue(args, result); 324 Dart_SetReturnValue(args, result);
650 } 325 }
651 326
652 327
653 void FUNCTION_NAME(ServerSocket_Accept)(Dart_NativeArguments args) { 328 void FUNCTION_NAME(ServerSocket_Accept)(Dart_NativeArguments args) {
654 intptr_t socket = 329 intptr_t socket =
655 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); 330 BaseSocket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
656 intptr_t new_socket = ServerSocket::Accept(socket); 331 intptr_t new_socket = ServerSocket::Accept(socket);
657 if (new_socket >= 0) { 332 if (new_socket >= 0) {
658 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 1), new_socket); 333 BaseSocket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 1),
334 new_socket);
659 Dart_SetReturnValue(args, Dart_True()); 335 Dart_SetReturnValue(args, Dart_True());
660 } else if (new_socket == ServerSocket::kTemporaryFailure) { 336 } else if (new_socket == ServerSocket::kTemporaryFailure) {
661 Dart_SetReturnValue(args, Dart_False()); 337 Dart_SetReturnValue(args, Dart_False());
662 } else { 338 } else {
663 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 339 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
664 } 340 }
665 } 341 }
666 342
667 343
668 CObject* Socket::LookupRequest(const CObjectArray& request) { 344 CObject* Socket::LookupRequest(const CObjectArray& request) {
669 if ((request.Length() == 2) && request[0]->IsString() && 345 if ((request.Length() == 2) && request[0]->IsString() &&
670 request[1]->IsInt32()) { 346 request[1]->IsInt32()) {
671 CObjectString host(request[0]); 347 CObjectString host(request[0]);
672 CObjectInt32 type(request[1]); 348 CObjectInt32 type(request[1]);
673 CObject* result = NULL; 349 CObject* result = NULL;
674 OSError* os_error = NULL; 350 OSError* os_error = NULL;
675 AddressList<SocketAddress>* addresses = 351 AddressList<SocketAddress>* addresses =
676 Socket::LookupAddress(host.CString(), type.Value(), &os_error); 352 BaseSocket::LookupAddress(host.CString(), type.Value(), &os_error);
677 if (addresses != NULL) { 353 if (addresses != NULL) {
678 CObjectArray* array = 354 CObjectArray* array =
679 new CObjectArray(CObject::NewArray(addresses->count() + 1)); 355 new CObjectArray(CObject::NewArray(addresses->count() + 1));
680 array->SetAt(0, new CObjectInt32(CObject::NewInt32(0))); 356 array->SetAt(0, new CObjectInt32(CObject::NewInt32(0)));
681 for (intptr_t i = 0; i < addresses->count(); i++) { 357 for (intptr_t i = 0; i < addresses->count(); i++) {
682 SocketAddress* addr = addresses->GetAt(i); 358 SocketAddress* addr = addresses->GetAt(i);
683 CObjectArray* entry = new CObjectArray(CObject::NewArray(3)); 359 CObjectArray* entry = new CObjectArray(CObject::NewArray(3));
684 360
685 CObjectInt32* type = 361 CObjectInt32* type =
686 new CObjectInt32(CObject::NewInt32(addr->GetType())); 362 new CObjectInt32(CObject::NewInt32(addr->GetType()));
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 delete addresses; 458 delete addresses;
783 } else { 459 } else {
784 result = CObject::NewOSError(os_error); 460 result = CObject::NewOSError(os_error);
785 delete os_error; 461 delete os_error;
786 } 462 }
787 return result; 463 return result;
788 } 464 }
789 return CObject::IllegalArgumentError(); 465 return CObject::IllegalArgumentError();
790 } 466 }
791 467
792
793 void FUNCTION_NAME(Socket_GetOption)(Dart_NativeArguments args) {
794 intptr_t socket =
795 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
796 int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
797 intptr_t protocol = static_cast<intptr_t>(
798 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2)));
799 bool ok = false;
800 switch (option) {
801 case 0: { // TCP_NODELAY.
802 bool enabled;
803 ok = Socket::GetNoDelay(socket, &enabled);
804 if (ok) {
805 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
806 }
807 break;
808 }
809 case 1: { // IP_MULTICAST_LOOP.
810 bool enabled;
811 ok = Socket::GetMulticastLoop(socket, protocol, &enabled);
812 if (ok) {
813 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
814 }
815 break;
816 }
817 case 2: { // IP_MULTICAST_TTL.
818 int value;
819 ok = Socket::GetMulticastHops(socket, protocol, &value);
820 if (ok) {
821 Dart_SetReturnValue(args, Dart_NewInteger(value));
822 }
823 break;
824 }
825 case 3: { // IP_MULTICAST_IF.
826 UNIMPLEMENTED();
827 break;
828 }
829 case 4: { // IP_BROADCAST.
830 bool enabled;
831 ok = Socket::GetBroadcast(socket, &enabled);
832 if (ok) {
833 Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
834 }
835 break;
836 }
837 default:
838 UNREACHABLE();
839 break;
840 }
841 // In case of failure the return value is not set above.
842 if (!ok) {
843 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
844 }
845 }
846
847
848 void FUNCTION_NAME(Socket_SetOption)(Dart_NativeArguments args) {
849 bool result = false;
850 intptr_t socket =
851 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
852 int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
853 int64_t protocol = DartUtils::GetInt64ValueCheckRange(
854 Dart_GetNativeArgument(args, 2), SocketAddress::TYPE_IPV4,
855 SocketAddress::TYPE_IPV6);
856 switch (option) {
857 case 0: // TCP_NODELAY.
858 result = Socket::SetNoDelay(
859 socket, DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
860 break;
861 case 1: // IP_MULTICAST_LOOP.
862 result = Socket::SetMulticastLoop(
863 socket, protocol,
864 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
865 break;
866 case 2: // IP_MULTICAST_TTL.
867 result = Socket::SetMulticastHops(
868 socket, protocol,
869 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3)));
870 break;
871 case 3: { // IP_MULTICAST_IF.
872 UNIMPLEMENTED();
873 break;
874 }
875 case 4: // IP_BROADCAST.
876 result = Socket::SetBroadcast(
877 socket, DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)));
878 break;
879 default:
880 Dart_PropagateError(Dart_NewApiError("Value outside expected range"));
881 break;
882 }
883 if (result) {
884 Dart_SetReturnValue(args, Dart_Null());
885 } else {
886 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
887 }
888 }
889
890
891 void FUNCTION_NAME(Socket_JoinMulticast)(Dart_NativeArguments args) {
892 intptr_t socket =
893 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
894 RawAddr addr;
895 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
896 RawAddr interface;
897 if (Dart_GetNativeArgument(args, 2) != Dart_Null()) {
898 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 2), &interface);
899 }
900 int interfaceIndex =
901 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
902 if (Socket::JoinMulticast(socket, addr, interface, interfaceIndex)) {
903 Dart_SetReturnValue(args, Dart_Null());
904 } else {
905 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
906 }
907 }
908
909
910 void FUNCTION_NAME(Socket_LeaveMulticast)(Dart_NativeArguments args) {
911 intptr_t socket =
912 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
913 RawAddr addr;
914 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
915 RawAddr interface;
916 if (Dart_GetNativeArgument(args, 2) != Dart_Null()) {
917 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 2), &interface);
918 }
919 int interfaceIndex =
920 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
921 if (Socket::LeaveMulticast(socket, addr, interface, interfaceIndex)) {
922 Dart_SetReturnValue(args, Dart_Null());
923 } else {
924 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
925 }
926 }
927
928
929 void Socket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) {
930 Dart_Handle err =
931 Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id);
932 if (Dart_IsError(err)) {
933 Dart_PropagateError(err);
934 }
935 }
936
937
938 intptr_t Socket::GetSocketIdNativeField(Dart_Handle socket_obj) {
939 intptr_t socket = 0;
940 Dart_Handle err =
941 Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &socket);
942 if (Dart_IsError(err)) {
943 Dart_PropagateError(err);
944 }
945 return socket;
946 }
947
948 } // namespace bin 468 } // namespace bin
949 } // namespace dart 469 } // namespace dart
950 470
951 #endif // !defined(DART_IO_DISABLED) 471 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« runtime/bin/socket.h ('K') | « runtime/bin/socket.h ('k') | runtime/bin/socket_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698