| OLD | NEW |
| 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 _sockaddr_storage[_IPV4_ADDR_OFFSET] < 240; | 118 _sockaddr_storage[_IPV4_ADDR_OFFSET] < 240; |
| 119 | 119 |
| 120 case InternetAddressType.IP_V6: | 120 case InternetAddressType.IP_V6: |
| 121 // Checking for ff00::/8. | 121 // Checking for ff00::/8. |
| 122 return _sockaddr_storage[_IPV6_ADDR_OFFSET] == 0xFF; | 122 return _sockaddr_storage[_IPV6_ADDR_OFFSET] == 0xFF; |
| 123 } | 123 } |
| 124 } | 124 } |
| 125 | 125 |
| 126 Future<InternetAddress> reverse() => _NativeSocket.reverseLookup(this); | 126 Future<InternetAddress> reverse() => _NativeSocket.reverseLookup(this); |
| 127 | 127 |
| 128 |
| 128 _InternetAddress(InternetAddressType this.type, | 129 _InternetAddress(InternetAddressType this.type, |
| 129 String this.address, | 130 String this.address, |
| 130 String this._host, | 131 String this._host, |
| 131 List<int> this._sockaddr_storage); | 132 List<int> this._sockaddr_storage); |
| 132 | 133 |
| 133 factory _InternetAddress.parse(String address) { | 134 factory _InternetAddress.parse(String address) { |
| 134 var type = address.indexOf(':') == -1 | 135 var type = address.indexOf(':') == -1 |
| 135 ? InternetAddressType.IP_V4 | 136 ? InternetAddressType.IP_V4 |
| 136 : InternetAddressType.IP_V6; | 137 : InternetAddressType.IP_V6; |
| 137 var raw = _parse(type._value, address); | 138 var raw = _parse(type._value, address); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 int eventMask = 0; | 258 int eventMask = 0; |
| 258 List eventHandlers; | 259 List eventHandlers; |
| 259 RawReceivePort eventPort; | 260 RawReceivePort eventPort; |
| 260 | 261 |
| 261 // Indicates if native interrupts can be activated. | 262 // Indicates if native interrupts can be activated. |
| 262 bool canActivateEvents = true; | 263 bool canActivateEvents = true; |
| 263 | 264 |
| 264 // The type flags for this socket. | 265 // The type flags for this socket. |
| 265 final int typeFlags; | 266 final int typeFlags; |
| 266 | 267 |
| 267 // Holds the port of the socket, null if not known. | 268 // Holds the port of the socket, 0 if not known. |
| 268 int localPort; | 269 int localPort = 0; |
| 269 | 270 |
| 270 // Holds the address used to connect or bind the socket. | 271 // Holds the address used to connect or bind the socket. |
| 271 InternetAddress address; | 272 InternetAddress address; |
| 272 | 273 |
| 273 static Future<List<InternetAddress>> lookup( | 274 static Future<List<InternetAddress>> lookup( |
| 274 String host, {InternetAddressType type: InternetAddressType.ANY}) { | 275 String host, {InternetAddressType type: InternetAddressType.ANY}) { |
| 275 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value]) | 276 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value]) |
| 276 .then((response) { | 277 .then((response) { |
| 277 if (isErrorResponse(response)) { | 278 if (isErrorResponse(response)) { |
| 278 throw createError(response, "Failed host lookup: '$host'"); | 279 throw createError(response, "Failed host lookup: '$host'"); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 throw new SocketException("Failed to create server socket", | 393 throw new SocketException("Failed to create server socket", |
| 393 osError: result, | 394 osError: result, |
| 394 address: address, | 395 address: address, |
| 395 port: port); | 396 port: port); |
| 396 } | 397 } |
| 397 if (port != 0) socket.localPort = port; | 398 if (port != 0) socket.localPort = port; |
| 398 return socket; | 399 return socket; |
| 399 }); | 400 }); |
| 400 } | 401 } |
| 401 | 402 |
| 403 _NativeSocket.datagram(this.address, this.localPort) |
| 404 : typeFlags = TYPE_NORMAL_SOCKET { |
| 405 eventHandlers = new List(EVENT_COUNT + 1); |
| 406 nativeCreateBindDatagram(address._sockaddr_storage, localPort); |
| 407 } |
| 408 |
| 402 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { | 409 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { |
| 403 eventHandlers = new List(EVENT_COUNT + 1); | 410 eventHandlers = new List(EVENT_COUNT + 1); |
| 404 } | 411 } |
| 405 | 412 |
| 406 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { | 413 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { |
| 407 eventHandlers = new List(EVENT_COUNT + 1); | 414 eventHandlers = new List(EVENT_COUNT + 1); |
| 408 } | 415 } |
| 409 | 416 |
| 410 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { | 417 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { |
| 411 eventHandlers = new List(EVENT_COUNT + 1); | 418 eventHandlers = new List(EVENT_COUNT + 1); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 434 } | 441 } |
| 435 if (isClosing || isClosed) return null; | 442 if (isClosing || isClosed) return null; |
| 436 var result = nativeRead(len == null ? -1 : len); | 443 var result = nativeRead(len == null ? -1 : len); |
| 437 if (result is OSError) { | 444 if (result is OSError) { |
| 438 reportError(result, "Read failed"); | 445 reportError(result, "Read failed"); |
| 439 return null; | 446 return null; |
| 440 } | 447 } |
| 441 return result; | 448 return result; |
| 442 } | 449 } |
| 443 | 450 |
| 451 Datagram receive() { |
| 452 if (isClosing || isClosed) return null; |
| 453 var result = nativeRecvFrom(); |
| 454 if (result is OSError) { |
| 455 reportError(result, "Receive failed"); |
| 456 return null; |
| 457 } |
| 458 return result; |
| 459 } |
| 460 |
| 444 int write(List<int> buffer, int offset, int bytes) { | 461 int write(List<int> buffer, int offset, int bytes) { |
| 445 if (buffer is! List) throw new ArgumentError(); | 462 if (buffer is! List) throw new ArgumentError(); |
| 446 if (offset == null) offset = 0; | 463 if (offset == null) offset = 0; |
| 447 if (bytes == null) { | 464 if (bytes == null) { |
| 448 if (offset > buffer.length) { | 465 if (offset > buffer.length) { |
| 449 throw new RangeError.value(offset); | 466 throw new RangeError.value(offset); |
| 450 } | 467 } |
| 451 bytes = buffer.length - offset; | 468 bytes = buffer.length - offset; |
| 452 } | 469 } |
| 453 if (offset < 0) throw new RangeError.value(offset); | 470 if (offset < 0) throw new RangeError.value(offset); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 464 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); | 481 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); |
| 465 var result = | 482 var result = |
| 466 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); | 483 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); |
| 467 if (result is OSError) { | 484 if (result is OSError) { |
| 468 reportError(result, "Write failed"); | 485 reportError(result, "Write failed"); |
| 469 result = 0; | 486 result = 0; |
| 470 } | 487 } |
| 471 return result; | 488 return result; |
| 472 } | 489 } |
| 473 | 490 |
| 491 int sendTo(List<int> buffer, int offset, int bytes, |
| 492 InternetAddress address, int port) { |
| 493 if (isClosing || isClosed) return 0; |
| 494 _BufferAndStart bufferAndStart = |
| 495 _ensureFastAndSerializableByteData( |
| 496 buffer, offset, bytes); |
| 497 var result = nativeSendTo( |
| 498 bufferAndStart.buffer, bufferAndStart.start, bytes, |
| 499 address._sockaddr_storage, port); |
| 500 } |
| 501 |
| 474 _NativeSocket accept() { | 502 _NativeSocket accept() { |
| 475 // Don't issue accept if we're closing. | 503 // Don't issue accept if we're closing. |
| 476 if (isClosing || isClosed) return null; | 504 if (isClosing || isClosed) return null; |
| 477 var socket = new _NativeSocket.normal(); | 505 var socket = new _NativeSocket.normal(); |
| 478 if (nativeAccept(socket) != true) return null; | 506 if (nativeAccept(socket) != true) return null; |
| 479 socket.localPort = localPort; | 507 socket.localPort = localPort; |
| 480 socket.address = address; | 508 socket.address = address; |
| 481 return socket; | 509 return socket; |
| 482 } | 510 } |
| 483 | 511 |
| 484 int get port { | 512 int get port { |
| 485 if (localPort != null) return localPort; | 513 if (localPort != 0) return localPort; |
| 486 return localPort = nativeGetPort(); | 514 return localPort = nativeGetPort(); |
| 487 } | 515 } |
| 488 | 516 |
| 489 int get remotePort { | 517 int get remotePort { |
| 490 return nativeGetRemotePeer()[1]; | 518 return nativeGetRemotePeer()[1]; |
| 491 } | 519 } |
| 492 | 520 |
| 493 InternetAddress get remoteAddress { | 521 InternetAddress get remoteAddress { |
| 494 var result = nativeGetRemotePeer()[0]; | 522 var result = nativeGetRemotePeer()[0]; |
| 495 var type = new InternetAddressType._from(result[0]); | 523 var type = new InternetAddressType._from(result[0]); |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 void reportError(error, String message) { | 714 void reportError(error, String message) { |
| 687 var e = createError(error, message, address, localPort); | 715 var e = createError(error, message, address, localPort); |
| 688 // Invoke the error handler if any. | 716 // Invoke the error handler if any. |
| 689 if (eventHandlers[ERROR_EVENT] != null) { | 717 if (eventHandlers[ERROR_EVENT] != null) { |
| 690 eventHandlers[ERROR_EVENT](e); | 718 eventHandlers[ERROR_EVENT](e); |
| 691 } | 719 } |
| 692 // For all errors we close the socket | 720 // For all errors we close the socket |
| 693 close(); | 721 close(); |
| 694 } | 722 } |
| 695 | 723 |
| 696 bool setOption(SocketOption option, bool enabled) { | 724 bool getOption(SocketOption option) { |
| 697 if (option is! SocketOption) throw new ArgumentError(options); | 725 if (option is! SocketOption) throw new ArgumentError(options); |
| 698 if (enabled is! bool) throw new ArgumentError(enabled); | 726 var result = nativeGetOption(option._value); |
| 699 return nativeSetOption(option._value, enabled); | 727 if (result is OSError) throw result; |
| 728 return result; |
| 729 } |
| 730 |
| 731 bool setOption(SocketOption option, value) { |
| 732 if (option is! SocketOption) throw new ArgumentError(options); |
| 733 var result = nativeSetOption(option._value, value); |
| 734 if (result is OSError) throw result; |
| 735 } |
| 736 |
| 737 void join(InternetAddress addr, NetworkInterface interface) { |
| 738 var result = nativeJoinMulticast(addr._sockaddr_storage, 0); |
| 739 if (result is OSError) throw result; |
| 740 } |
| 741 |
| 742 void leave(InternetAddress addr, NetworkInterface interface) { |
| 743 var result = nativeLeaveMulticast(addr._sockaddr_storage, 0); |
| 744 if (result is OSError) throw result; |
| 700 } | 745 } |
| 701 | 746 |
| 702 void nativeSetSocketId(int id) native "Socket_SetSocketId"; | 747 void nativeSetSocketId(int id) native "Socket_SetSocketId"; |
| 703 nativeAvailable() native "Socket_Available"; | 748 nativeAvailable() native "Socket_Available"; |
| 704 nativeRead(int len) native "Socket_Read"; | 749 nativeRead(int len) native "Socket_Read"; |
| 750 nativeRecvFrom() native "Socket_RecvFrom"; |
| 705 nativeWrite(List<int> buffer, int offset, int bytes) | 751 nativeWrite(List<int> buffer, int offset, int bytes) |
| 706 native "Socket_WriteList"; | 752 native "Socket_WriteList"; |
| 753 nativeSendTo(List<int> buffer, int offset, int bytes, |
| 754 List<int> address, int port) |
| 755 native "Socket_SendTo"; |
| 707 nativeCreateConnect(List<int> addr, | 756 nativeCreateConnect(List<int> addr, |
| 708 int port) native "Socket_CreateConnect"; | 757 int port) native "Socket_CreateConnect"; |
| 758 nativeCreateBindDatagram(List<int> addr, |
| 759 int port) native "Socket_CreateBindDatagram"; |
| 709 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only) | 760 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only) |
| 710 native "ServerSocket_CreateBindListen"; | 761 native "ServerSocket_CreateBindListen"; |
| 711 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; | 762 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; |
| 712 int nativeGetPort() native "Socket_GetPort"; | 763 int nativeGetPort() native "Socket_GetPort"; |
| 713 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; | 764 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; |
| 714 OSError nativeGetError() native "Socket_GetError"; | 765 OSError nativeGetError() native "Socket_GetError"; |
| 766 nativeGetOption(int option) native "Socket_GetOption"; |
| 715 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; | 767 bool nativeSetOption(int option, bool enabled) native "Socket_SetOption"; |
| 768 bool nativeJoinMulticast(List<int> addr, int interface) |
| 769 native "Socket_JoinMulticast"; |
| 770 bool nativeLeaveMulticast(List<int> addr, int interface) |
| 771 native "Socket_LeaveMulticast"; |
| 716 } | 772 } |
| 717 | 773 |
| 718 | 774 |
| 719 class _RawServerSocket extends Stream<RawSocket> | 775 class _RawServerSocket extends Stream<RawSocket> |
| 720 implements RawServerSocket { | 776 implements RawServerSocket { |
| 721 final _NativeSocket _socket; | 777 final _NativeSocket _socket; |
| 722 StreamController<RawSocket> _controller; | 778 StreamController<RawSocket> _controller; |
| 723 | 779 |
| 724 static Future<_RawServerSocket> bind(address, | 780 static Future<_RawServerSocket> bind(address, |
| 725 int port, | 781 int port, |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 if (_detachReady != null) { | 1324 if (_detachReady != null) { |
| 1269 _detachReady.complete(null); | 1325 _detachReady.complete(null); |
| 1270 } else { | 1326 } else { |
| 1271 if (_raw != null) { | 1327 if (_raw != null) { |
| 1272 _raw.shutdown(SocketDirection.SEND); | 1328 _raw.shutdown(SocketDirection.SEND); |
| 1273 _disableWriteEvent(); | 1329 _disableWriteEvent(); |
| 1274 } | 1330 } |
| 1275 } | 1331 } |
| 1276 } | 1332 } |
| 1277 } | 1333 } |
| 1334 |
| 1335 |
| 1336 class _RawDatagramSocket extends Stream implements RawDatagramSocket { |
| 1337 _NativeSocket _socket; |
| 1338 StreamController<RawSocketEvent> _controller; |
| 1339 bool _readEventsEnabled = true; |
| 1340 bool _writeEventsEnabled = true; |
| 1341 |
| 1342 _RawDatagramSocket(InternetAddress address, int port) { |
| 1343 _socket = new _NativeSocket.datagram(address, port); |
| 1344 _controller = new StreamController(sync: true, |
| 1345 onListen: _onSubscriptionStateChange, |
| 1346 onCancel: _onSubscriptionStateChange, |
| 1347 onPause: _onPauseStateChange, |
| 1348 onResume: _onPauseStateChange); |
| 1349 _socket.closeFuture.then((_) => _controller.close()); |
| 1350 _socket.setHandlers( |
| 1351 read: () => _controller.add(RawSocketEvent.READ), |
| 1352 write: () { |
| 1353 // The write event handler is automatically disabled by the |
| 1354 // event handler when it fires. |
| 1355 _writeEventsEnabled = false; |
| 1356 _controller.add(RawSocketEvent.WRITE); |
| 1357 }, |
| 1358 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), |
| 1359 destroyed: () => _controller.add(RawSocketEvent.CLOSED), |
| 1360 error: (e) { |
| 1361 _controller.addError(e); |
| 1362 close(); |
| 1363 } |
| 1364 ); |
| 1365 } |
| 1366 |
| 1367 StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event), |
| 1368 {Function onError, |
| 1369 void onDone(), |
| 1370 bool cancelOnError}) { |
| 1371 return _controller.stream.listen( |
| 1372 onData, |
| 1373 onError: onError, |
| 1374 onDone: onDone, |
| 1375 cancelOnError: cancelOnError); |
| 1376 } |
| 1377 |
| 1378 Future close() => _socket.close().then((_) => this); |
| 1379 |
| 1380 bool send(Datagram datagram) { |
| 1381 var result = _socket.sendTo(datagram.data, 0, datagram.data.length, |
| 1382 datagram.address, datagram.port); |
| 1383 if (result is OSError) { |
| 1384 throw result; |
| 1385 } |
| 1386 assert(result == datagram.data.length); |
| 1387 return true; |
| 1388 } |
| 1389 |
| 1390 bool sendTo(List<data> buffer, InternetAddress address, int port) { |
| 1391 var result = _socket.sendTo(buffer, 0, buffer.length, address, port); |
| 1392 if (result is OSError) { |
| 1393 throw result; |
| 1394 } |
| 1395 assert(result == buffer.length); |
| 1396 return true; |
| 1397 } |
| 1398 |
| 1399 Datagram receive() { |
| 1400 return _socket.receive(); |
| 1401 } |
| 1402 |
| 1403 void join(InternetAddress group, [NetworkInterface interface]) { |
| 1404 _socket.join(group, interface); |
| 1405 } |
| 1406 |
| 1407 void leave(InternetAddress group, [NetworkInterface interface]) { |
| 1408 _socket.leave(group, interface); |
| 1409 } |
| 1410 |
| 1411 bool get readEventsEnabled => _readEventsEnabled; |
| 1412 void set readEventsEnabled(bool value) { |
| 1413 if (value != _readEventsEnabled) { |
| 1414 _readEventsEnabled = value; |
| 1415 if (!_controller.isPaused) _resume(); |
| 1416 } |
| 1417 } |
| 1418 |
| 1419 bool get writeEventsEnabled => _writeEventsEnabled; |
| 1420 void set writeEventsEnabled(bool value) { |
| 1421 if (value != _writeEventsEnabled) { |
| 1422 _writeEventsEnabled = value; |
| 1423 if (!_controller.isPaused) _resume(); |
| 1424 } |
| 1425 } |
| 1426 |
| 1427 bool get multicastLoopback => |
| 1428 _socket.getOption(SocketOption._IP_MULTICAST_LOOP); |
| 1429 void set multicastLoopback(bool value) => |
| 1430 _socket.setOption(SocketOption._IP_MULTICAST_LOOP, value); |
| 1431 |
| 1432 int get multicastTTL => |
| 1433 _socket.getOption(SocketOption._IP_MULTICAST_TTL); |
| 1434 void set multicastTTL(int value) => |
| 1435 _socket.setOption(SocketOption._IP_MULTICAST_TTL, value); |
| 1436 |
| 1437 bool get broadcastEnabled => |
| 1438 _socket.getOption(SocketOption._IP_BROADCAST); |
| 1439 void set broadcastEnabled(bool value) => |
| 1440 _socket.setOption(SocketOption._IP_BROADCAST, value); |
| 1441 |
| 1442 int get port => _socket.port; |
| 1443 |
| 1444 InternetAddress get address => _socket.address; |
| 1445 |
| 1446 _pause() { |
| 1447 _socket.setListening(read: false, write: false); |
| 1448 } |
| 1449 |
| 1450 void _resume() { |
| 1451 _socket.setListening(read: _readEventsEnabled, write: _writeEventsEnabled); |
| 1452 } |
| 1453 |
| 1454 void _onPauseStateChange() { |
| 1455 if (_controller.isPaused) { |
| 1456 _pause(); |
| 1457 } else { |
| 1458 _resume(); |
| 1459 } |
| 1460 } |
| 1461 |
| 1462 void _onSubscriptionStateChange() { |
| 1463 if (_controller.hasListener) { |
| 1464 _resume(); |
| 1465 } else { |
| 1466 close(); |
| 1467 } |
| 1468 } |
| 1469 } |
| 1470 |
| 1471 Datagram _makeDatagram(List<int> data, |
| 1472 bool ipV6, |
| 1473 String address, |
| 1474 List<int> sockaddr_storage, |
| 1475 int port) { |
| 1476 var addressType = |
| 1477 ipV6 ? InternetAddressType.IP_V6 : InternetAddressType.IP_V4; |
| 1478 return new Datagram( |
| 1479 data, |
| 1480 new _InternetAddress(addressType, address, null, sockaddr_storage), |
| 1481 port); |
| 1482 } |
| OLD | NEW |