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

Side by Side Diff: runtime/bin/socket_patch.dart

Issue 85993002: Add UDP support to dart:io (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix Windows build 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
« no previous file with comments | « runtime/bin/socket_macos.cc ('k') | runtime/bin/socket_win.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 patch class RawServerSocket { 5 patch class RawServerSocket {
6 /* patch */ static Future<RawServerSocket> bind(address, 6 /* patch */ static Future<RawServerSocket> bind(address,
7 int port, 7 int port,
8 {int backlog: 0, 8 {int backlog: 0,
9 bool v6Only: false}) { 9 bool v6Only: false}) {
10 return _RawServerSocket.bind(address, port, backlog, v6Only); 10 return _RawServerSocket.bind(address, port, backlog, v6Only);
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 static const int PIPE_SOCKET = 17; 240 static const int PIPE_SOCKET = 17;
241 static const int TYPE_NORMAL_SOCKET = 0; 241 static const int TYPE_NORMAL_SOCKET = 0;
242 static const int TYPE_LISTENING_SOCKET = 1 << LISTENING_SOCKET; 242 static const int TYPE_LISTENING_SOCKET = 1 << LISTENING_SOCKET;
243 static const int TYPE_PIPE = 1 << PIPE_SOCKET; 243 static const int TYPE_PIPE = 1 << PIPE_SOCKET;
244 244
245 // Native port messages. 245 // Native port messages.
246 static const HOST_NAME_LOOKUP = 0; 246 static const HOST_NAME_LOOKUP = 0;
247 static const LIST_INTERFACES = 1; 247 static const LIST_INTERFACES = 1;
248 static const REVERSE_LOOKUP = 2; 248 static const REVERSE_LOOKUP = 2;
249 249
250 // Protocol flags.
251 static const int PROTOCOL_IPV4 = 1 << 0;
252 static const int PROTOCOL_IPV6 = 1 << 1;
253
250 // Socket close state 254 // Socket close state
251 bool isClosed = false; 255 bool isClosed = false;
252 bool isClosing = false; 256 bool isClosing = false;
253 bool isClosedRead = false; 257 bool isClosedRead = false;
254 bool isClosedWrite = false; 258 bool isClosedWrite = false;
255 Completer closeCompleter = new Completer(); 259 Completer closeCompleter = new Completer();
256 260
257 // Handlers and receive port for socket events from the event handler. 261 // Handlers and receive port for socket events from the event handler.
258 int eventMask = 0; 262 int eventMask = 0;
259 List eventHandlers; 263 List eventHandlers;
260 RawReceivePort eventPort; 264 RawReceivePort eventPort;
261 265
262 // Indicates if native interrupts can be activated. 266 // Indicates if native interrupts can be activated.
263 bool canActivateEvents = true; 267 bool canActivateEvents = true;
264 268
265 // The type flags for this socket. 269 // The type flags for this socket.
266 final int typeFlags; 270 final int typeFlags;
267 271
268 // Holds the port of the socket, null if not known. 272 // Holds the port of the socket, 0 if not known.
269 int localPort; 273 int localPort = 0;
270 274
271 // Holds the address used to connect or bind the socket. 275 // Holds the address used to connect or bind the socket.
272 InternetAddress address; 276 InternetAddress address;
273 277
274 static Future<List<InternetAddress>> lookup( 278 static Future<List<InternetAddress>> lookup(
275 String host, {InternetAddressType type: InternetAddressType.ANY}) { 279 String host, {InternetAddressType type: InternetAddressType.ANY}) {
276 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value]) 280 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value])
277 .then((response) { 281 .then((response) {
278 if (isErrorResponse(response)) { 282 if (isErrorResponse(response)) {
279 throw createError(response, "Failed host lookup: '$host'"); 283 throw createError(response, "Failed host lookup: '$host'");
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 throw new SocketException("Failed to create server socket", 395 throw new SocketException("Failed to create server socket",
392 osError: result, 396 osError: result,
393 address: address, 397 address: address,
394 port: port); 398 port: port);
395 } 399 }
396 if (port != 0) socket.localPort = port; 400 if (port != 0) socket.localPort = port;
397 return socket; 401 return socket;
398 }); 402 });
399 } 403 }
400 404
405 static Future<_NativeSocket> bindDatagram(
406 host, int port, bool reuseAddress) {
407 return new Future.value(host)
408 .then((host) {
409 if (host is _InternetAddress) return host;
410 return lookup(host)
411 .then((list) {
412 if (list.length == 0) {
413 throw createError(response, "Failed host lookup: '$host'");
414 }
415 return list[0];
416 });
417 })
418 .then((address) {
419 var socket = new _NativeSocket.datagram(address);
420 var result = socket.nativeCreateBindDatagram(
421 address._sockaddr_storage, port, reuseAddress);
422 if (result is OSError) {
423 throw new SocketException("Failed to create datagram socket",
424 osError: result,
425 address: address,
426 port: port);
427 }
428 if (port != 0) socket.localPort = port;
429 return socket;
430 });
431 }
432
433 _NativeSocket.datagram(this.address)
434 : typeFlags = TYPE_NORMAL_SOCKET {
435 eventHandlers = new List(EVENT_COUNT + 1);
436 }
437
401 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { 438 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET {
402 eventHandlers = new List(EVENT_COUNT + 1); 439 eventHandlers = new List(EVENT_COUNT + 1);
403 } 440 }
404 441
405 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { 442 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET {
406 eventHandlers = new List(EVENT_COUNT + 1); 443 eventHandlers = new List(EVENT_COUNT + 1);
407 } 444 }
408 445
409 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { 446 _NativeSocket.pipe() : typeFlags = TYPE_PIPE {
410 eventHandlers = new List(EVENT_COUNT + 1); 447 eventHandlers = new List(EVENT_COUNT + 1);
(...skipping 22 matching lines...) Expand all
433 } 470 }
434 if (isClosing || isClosed) return null; 471 if (isClosing || isClosed) return null;
435 var result = nativeRead(len == null ? -1 : len); 472 var result = nativeRead(len == null ? -1 : len);
436 if (result is OSError) { 473 if (result is OSError) {
437 reportError(result, "Read failed"); 474 reportError(result, "Read failed");
438 return null; 475 return null;
439 } 476 }
440 return result; 477 return result;
441 } 478 }
442 479
480 Datagram receive() {
481 if (isClosing || isClosed) return null;
482 var result = nativeRecvFrom();
483 if (result is OSError) {
484 reportError(result, "Receive failed");
485 return null;
486 }
487 return result;
488 }
489
443 int write(List<int> buffer, int offset, int bytes) { 490 int write(List<int> buffer, int offset, int bytes) {
444 if (buffer is! List) throw new ArgumentError(); 491 if (buffer is! List) throw new ArgumentError();
445 if (offset == null) offset = 0; 492 if (offset == null) offset = 0;
446 if (bytes == null) { 493 if (bytes == null) {
447 if (offset > buffer.length) { 494 if (offset > buffer.length) {
448 throw new RangeError.value(offset); 495 throw new RangeError.value(offset);
449 } 496 }
450 bytes = buffer.length - offset; 497 bytes = buffer.length - offset;
451 } 498 }
452 if (offset < 0) throw new RangeError.value(offset); 499 if (offset < 0) throw new RangeError.value(offset);
(...skipping 10 matching lines...) Expand all
463 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); 510 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes);
464 var result = 511 var result =
465 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); 512 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes);
466 if (result is OSError) { 513 if (result is OSError) {
467 scheduleMicrotask(() => reportError(result, "Write failed")); 514 scheduleMicrotask(() => reportError(result, "Write failed"));
468 result = 0; 515 result = 0;
469 } 516 }
470 return result; 517 return result;
471 } 518 }
472 519
520 int send(List<int> buffer, int offset, int bytes,
521 InternetAddress address, int port) {
522 if (isClosing || isClosed) return 0;
523 _BufferAndStart bufferAndStart =
524 _ensureFastAndSerializableByteData(
525 buffer, offset, bytes);
526 var result = nativeSendTo(
527 bufferAndStart.buffer, bufferAndStart.start, bytes,
528 address._sockaddr_storage, port);
529 if (result is OSError) {
530 scheduleMicrotask(() => reportError(result, "Send failed"));
531 result = 0;
532 }
533 return result;
534 }
535
473 _NativeSocket accept() { 536 _NativeSocket accept() {
474 // Don't issue accept if we're closing. 537 // Don't issue accept if we're closing.
475 if (isClosing || isClosed) return null; 538 if (isClosing || isClosed) return null;
476 var socket = new _NativeSocket.normal(); 539 var socket = new _NativeSocket.normal();
477 if (nativeAccept(socket) != true) return null; 540 if (nativeAccept(socket) != true) return null;
478 socket.localPort = localPort; 541 socket.localPort = localPort;
479 socket.address = address; 542 socket.address = address;
480 return socket; 543 return socket;
481 } 544 }
482 545
483 int get port { 546 int get port {
484 if (localPort != null) return localPort; 547 if (localPort != 0) return localPort;
485 return localPort = nativeGetPort(); 548 return localPort = nativeGetPort();
486 } 549 }
487 550
488 int get remotePort { 551 int get remotePort {
489 return nativeGetRemotePeer()[1]; 552 return nativeGetRemotePeer()[1];
490 } 553 }
491 554
492 InternetAddress get remoteAddress { 555 InternetAddress get remoteAddress {
493 var result = nativeGetRemotePeer()[0]; 556 var result = nativeGetRemotePeer()[0];
494 var type = new InternetAddressType._from(result[0]); 557 var type = new InternetAddressType._from(result[0]);
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 void reportError(error, String message) { 753 void reportError(error, String message) {
691 var e = createError(error, message, address, localPort); 754 var e = createError(error, message, address, localPort);
692 // Invoke the error handler if any. 755 // Invoke the error handler if any.
693 if (eventHandlers[ERROR_EVENT] != null) { 756 if (eventHandlers[ERROR_EVENT] != null) {
694 eventHandlers[ERROR_EVENT](e); 757 eventHandlers[ERROR_EVENT](e);
695 } 758 }
696 // For all errors we close the socket 759 // For all errors we close the socket
697 close(); 760 close();
698 } 761 }
699 762
700 bool setOption(SocketOption option, bool enabled) { 763 getOption(SocketOption option) {
701 if (option is! SocketOption) throw new ArgumentError(options); 764 if (option is! SocketOption) throw new ArgumentError(options);
702 if (enabled is! bool) throw new ArgumentError(enabled); 765 var result = nativeGetOption(option._value, address.type._value);
703 return nativeSetOption(option._value, enabled); 766 if (result is OSError) throw result;
767 return result;
768 }
769
770 bool setOption(SocketOption option, value) {
771 if (option is! SocketOption) throw new ArgumentError(options);
772 var result = nativeSetOption(option._value, address.type._value, value);
773 if (result is OSError) throw result;
774 }
775
776 InternetAddress multicastAddress(
777 InternetAddress addr, NetworkInterface interface) {
778 // On Mac OS using the interface index for joining IPv4 multicast groups
779 // is not supported. Here the IP address of the interface is needed.
780 if (Platform.isMacOS && addr.type == InternetAddressType.IP_V4) {
781 if (interface != null) {
782 for (int i = 0; i < interface.addresses.length; i++) {
783 if (addr.type == InternetAddressType.IP_V4) {
784 return interface.addresses[i];
785 }
786 }
787 // No IPv4 address found on the interface.
788 throw new SocketException(
789 "The network interface does not have an address "
790 "of the same family as the multicast address");
791 } else {
792 // Default to the ANY address if on iterface is specified.
793 return InternetAddress.ANY_IP_V4;
794 }
795 } else {
796 return null;
797 }
798 }
799
800 void joinMulticast(InternetAddress addr, NetworkInterface interface) {
801 var interfaceAddr = multicastAddress(addr, interface);
802 var interfaceIndex = interface == null ? 0 : interface.index;
803 var result = nativeJoinMulticast(
804 addr._sockaddr_storage,
805 interfaceAddr == null ? null : interfaceAddr._sockaddr_storage,
806 interfaceIndex);
807 if (result is OSError) throw result;
808 }
809
810 void leaveMulticast(InternetAddress addr, NetworkInterface interface) {
811 var interfaceAddr = multicastAddress(addr, interface);
812 var interfaceIndex = interface == null ? 0 : interface.index;
813 var result = nativeLeaveMulticast(
814 addr._sockaddr_storage,
815 interfaceAddr == null ? null : interfaceAddr._sockaddr_storage,
816 interfaceIndex);
817 if (result is OSError) throw result;
704 } 818 }
705 819
706 void nativeSetSocketId(int id) native "Socket_SetSocketId"; 820 void nativeSetSocketId(int id) native "Socket_SetSocketId";
707 nativeAvailable() native "Socket_Available"; 821 nativeAvailable() native "Socket_Available";
708 nativeRead(int len) native "Socket_Read"; 822 nativeRead(int len) native "Socket_Read";
823 nativeRecvFrom() native "Socket_RecvFrom";
709 nativeWrite(List<int> buffer, int offset, int bytes) 824 nativeWrite(List<int> buffer, int offset, int bytes)
710 native "Socket_WriteList"; 825 native "Socket_WriteList";
826 nativeSendTo(List<int> buffer, int offset, int bytes,
827 List<int> address, int port)
828 native "Socket_SendTo";
711 nativeCreateConnect(List<int> addr, 829 nativeCreateConnect(List<int> addr,
712 int port) native "Socket_CreateConnect"; 830 int port) native "Socket_CreateConnect";
713 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only) 831 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only)
714 native "ServerSocket_CreateBindListen"; 832 native "ServerSocket_CreateBindListen";
833 nativeCreateBindDatagram(List<int> addr, int port, bool reuseAddress)
834 native "Socket_CreateBindDatagram";
715 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; 835 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept";
716 int nativeGetPort() native "Socket_GetPort"; 836 int nativeGetPort() native "Socket_GetPort";
717 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; 837 List nativeGetRemotePeer() native "Socket_GetRemotePeer";
718 OSError nativeGetError() native "Socket_GetError"; 838 OSError nativeGetError() native "Socket_GetError";
719 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; 839 nativeGetOption(int option, int protocol) native "Socket_GetOption";
840 bool nativeSetOption(int option, int protocol, value)
841 native "Socket_SetOption";
842 bool nativeJoinMulticast(
843 List<int> addr, List<int> interfaceAddr, int interfaceIndex)
844 native "Socket_JoinMulticast";
845 bool nativeLeaveMulticast(
846 List<int> addr, List<int> interfaceAddr, int interfaceIndex)
847 native "Socket_LeaveMulticast";
720 } 848 }
721 849
722 850
723 class _RawServerSocket extends Stream<RawSocket> 851 class _RawServerSocket extends Stream<RawSocket>
724 implements RawServerSocket { 852 implements RawServerSocket {
725 final _NativeSocket _socket; 853 final _NativeSocket _socket;
726 StreamController<RawSocket> _controller; 854 StreamController<RawSocket> _controller;
727 855
728 static Future<_RawServerSocket> bind(address, 856 static Future<_RawServerSocket> bind(address,
729 int port, 857 int port,
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 if (_detachReady != null) { 1402 if (_detachReady != null) {
1275 _detachReady.complete(null); 1403 _detachReady.complete(null);
1276 } else { 1404 } else {
1277 if (_raw != null) { 1405 if (_raw != null) {
1278 _raw.shutdown(SocketDirection.SEND); 1406 _raw.shutdown(SocketDirection.SEND);
1279 _disableWriteEvent(); 1407 _disableWriteEvent();
1280 } 1408 }
1281 } 1409 }
1282 } 1410 }
1283 } 1411 }
1412
1413
1414 patch class RawDatagramSocket {
1415 /* patch */ static Future<RawDatagramSocket> bind(
1416 host, int port, {bool reuseAddress: true}) {
1417 return _RawDatagramSocket.bind(host, port, reuseAddress);
1418 }
1419 }
1420
1421 class _RawDatagramSocket extends Stream implements RawDatagramSocket {
1422 _NativeSocket _socket;
1423 StreamController<RawSocketEvent> _controller;
1424 bool _readEventsEnabled = true;
1425 bool _writeEventsEnabled = true;
1426
1427 _RawDatagramSocket(this._socket) {
1428 var zone = Zone.current;
1429 _controller = new StreamController(sync: true,
1430 onListen: _onSubscriptionStateChange,
1431 onCancel: _onSubscriptionStateChange,
1432 onPause: _onPauseStateChange,
1433 onResume: _onPauseStateChange);
1434 _socket.closeFuture.then((_) => _controller.close());
1435 _socket.setHandlers(
1436 read: () => _controller.add(RawSocketEvent.READ),
1437 write: () {
1438 // The write event handler is automatically disabled by the
1439 // event handler when it fires.
1440 _writeEventsEnabled = false;
1441 _controller.add(RawSocketEvent.WRITE);
1442 },
1443 closed: () => _controller.add(RawSocketEvent.READ_CLOSED),
1444 destroyed: () => _controller.add(RawSocketEvent.CLOSED),
1445 error: zone.bindUnaryCallback((e) {
1446 _controller.addError(e);
1447 close();
1448 })
1449 );
1450 }
1451
1452 static Future<RawDatagramSocket> bind(
1453 host, int port, bool reuseAddress) {
1454 if (port < 0 || port > 0xffff)
1455 throw new ArgumentError("Invalid port $port");
1456 return _NativeSocket.bindDatagram(host, port, reuseAddress)
1457 .then((socket) => new _RawDatagramSocket(socket));
1458 }
1459
1460 StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event),
1461 {Function onError,
1462 void onDone(),
1463 bool cancelOnError}) {
1464 return _controller.stream.listen(
1465 onData,
1466 onError: onError,
1467 onDone: onDone,
1468 cancelOnError: cancelOnError);
1469 }
1470
1471 Future close() => _socket.close().then((_) => this);
1472
1473 int send(List<data> buffer, InternetAddress address, int port) =>
1474 _socket.send(buffer, 0, buffer.length, address, port);
1475
1476 Datagram receive() {
1477 return _socket.receive();
1478 }
1479
1480 void joinMulticast(InternetAddress group, [NetworkInterface interface]) {
1481 _socket.joinMulticast(group, interface);
1482 }
1483
1484 void leaveMulticast(InternetAddress group, [NetworkInterface interface]) {
1485 _socket.leaveMulticast(group, interface);
1486 }
1487
1488 bool get readEventsEnabled => _readEventsEnabled;
1489 void set readEventsEnabled(bool value) {
1490 if (value != _readEventsEnabled) {
1491 _readEventsEnabled = value;
1492 if (!_controller.isPaused) _resume();
1493 }
1494 }
1495
1496 bool get writeEventsEnabled => _writeEventsEnabled;
1497 void set writeEventsEnabled(bool value) {
1498 if (value != _writeEventsEnabled) {
1499 _writeEventsEnabled = value;
1500 if (!_controller.isPaused) _resume();
1501 }
1502 }
1503
1504 bool get multicastLoopback =>
1505 _socket.getOption(SocketOption._IP_MULTICAST_LOOP);
1506 void set multicastLoopback(bool value) =>
1507 _socket.setOption(SocketOption._IP_MULTICAST_LOOP, value);
1508
1509 int get multicastHops =>
1510 _socket.getOption(SocketOption._IP_MULTICAST_HOPS);
1511 void set multicastHops(int value) =>
1512 _socket.setOption(SocketOption._IP_MULTICAST_HOPS, value);
1513
1514 NetworkInterface get multicastInterface =>
1515 throw "Not implemented";
1516 void set multicastInterface(NetworkInterface value) =>
1517 throw "Not implemented";
1518
1519 bool get broadcastEnabled =>
1520 _socket.getOption(SocketOption._IP_BROADCAST);
1521 void set broadcastEnabled(bool value) =>
1522 _socket.setOption(SocketOption._IP_BROADCAST, value);
1523
1524 int get port => _socket.port;
1525
1526 InternetAddress get address => _socket.address;
1527
1528 _pause() {
1529 _socket.setListening(read: false, write: false);
1530 }
1531
1532 void _resume() {
1533 _socket.setListening(read: _readEventsEnabled, write: _writeEventsEnabled);
1534 }
1535
1536 void _onPauseStateChange() {
1537 if (_controller.isPaused) {
1538 _pause();
1539 } else {
1540 _resume();
1541 }
1542 }
1543
1544 void _onSubscriptionStateChange() {
1545 if (_controller.hasListener) {
1546 _resume();
1547 } else {
1548 close();
1549 }
1550 }
1551 }
1552
1553 Datagram _makeDatagram(List<int> data,
1554 bool ipV6,
1555 String address,
1556 List<int> sockaddr_storage,
1557 int port) {
1558 var addressType =
1559 ipV6 ? InternetAddressType.IP_V6 : InternetAddressType.IP_V4;
1560 return new Datagram(
1561 data,
1562 new _InternetAddress(addressType, address, null, sockaddr_storage),
1563 port);
1564 }
OLDNEW
« no previous file with comments | « runtime/bin/socket_macos.cc ('k') | runtime/bin/socket_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698