| 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 | 5 @patch class RawServerSocket { |
| 6 class RawServerSocket { | 6 @patch static Future<RawServerSocket> bind(address, |
| 7 @patch | 7 int port, |
| 8 static Future<RawServerSocket> bind(address, int port, | 8 {int backlog: 0, |
| 9 {int backlog: 0, bool v6Only: false, bool shared: false}) { | 9 bool v6Only: false, |
| 10 bool shared: false}) { |
| 10 return _RawServerSocket.bind(address, port, backlog, v6Only, shared); | 11 return _RawServerSocket.bind(address, port, backlog, v6Only, shared); |
| 11 } | 12 } |
| 12 } | 13 } |
| 13 | 14 |
| 14 @patch | 15 |
| 15 class RawSocket { | 16 @patch class RawSocket { |
| 16 @patch | 17 @patch static Future<RawSocket> connect( |
| 17 static Future<RawSocket> connect(host, int port, {sourceAddress}) { | 18 host, int port, {sourceAddress}) { |
| 18 return _RawSocket.connect(host, port, sourceAddress); | 19 return _RawSocket.connect(host, port, sourceAddress); |
| 19 } | 20 } |
| 20 } | 21 } |
| 21 | 22 |
| 22 @patch | 23 |
| 23 class InternetAddress { | 24 @patch class InternetAddress { |
| 24 @patch | 25 @patch static InternetAddress get LOOPBACK_IP_V4 { |
| 25 static InternetAddress get LOOPBACK_IP_V4 { | |
| 26 return _InternetAddress.LOOPBACK_IP_V4; | 26 return _InternetAddress.LOOPBACK_IP_V4; |
| 27 } | 27 } |
| 28 | 28 |
| 29 @patch | 29 @patch static InternetAddress get LOOPBACK_IP_V6 { |
| 30 static InternetAddress get LOOPBACK_IP_V6 { | |
| 31 return _InternetAddress.LOOPBACK_IP_V6; | 30 return _InternetAddress.LOOPBACK_IP_V6; |
| 32 } | 31 } |
| 33 | 32 |
| 34 @patch | 33 @patch static InternetAddress get ANY_IP_V4 { |
| 35 static InternetAddress get ANY_IP_V4 { | |
| 36 return _InternetAddress.ANY_IP_V4; | 34 return _InternetAddress.ANY_IP_V4; |
| 37 } | 35 } |
| 38 | 36 |
| 39 @patch | 37 @patch static InternetAddress get ANY_IP_V6 { |
| 40 static InternetAddress get ANY_IP_V6 { | |
| 41 return _InternetAddress.ANY_IP_V6; | 38 return _InternetAddress.ANY_IP_V6; |
| 42 } | 39 } |
| 43 | 40 |
| 44 @patch | 41 @patch factory InternetAddress(String address) { |
| 45 factory InternetAddress(String address) { | |
| 46 return new _InternetAddress.parse(address); | 42 return new _InternetAddress.parse(address); |
| 47 } | 43 } |
| 48 | 44 |
| 49 @patch | 45 @patch static Future<List<InternetAddress>> lookup( |
| 50 static Future<List<InternetAddress>> lookup(String host, | 46 String host, {InternetAddressType type: InternetAddressType.ANY}) { |
| 51 {InternetAddressType type: InternetAddressType.ANY}) { | |
| 52 return _NativeSocket.lookup(host, type: type); | 47 return _NativeSocket.lookup(host, type: type); |
| 53 } | 48 } |
| 54 | 49 |
| 55 @patch | 50 @patch static InternetAddress _cloneWithNewHost( |
| 56 static InternetAddress _cloneWithNewHost( | |
| 57 InternetAddress address, String host) { | 51 InternetAddress address, String host) { |
| 58 return (address as _InternetAddress)._cloneWithNewHost(host); | 52 return (address as _InternetAddress)._cloneWithNewHost(host); |
| 59 } | 53 } |
| 60 } | 54 } |
| 61 | 55 |
| 62 @patch | 56 @patch class NetworkInterface { |
| 63 class NetworkInterface { | 57 @patch static bool get listSupported { |
| 64 @patch | |
| 65 static bool get listSupported { | |
| 66 return _listSupported(); | 58 return _listSupported(); |
| 67 } | 59 } |
| 68 | 60 |
| 69 @patch | 61 @patch static Future<List<NetworkInterface>> list({ |
| 70 static Future<List<NetworkInterface>> list( | 62 bool includeLoopback: false, |
| 71 {bool includeLoopback: false, | |
| 72 bool includeLinkLocal: false, | 63 bool includeLinkLocal: false, |
| 73 InternetAddressType type: InternetAddressType.ANY}) { | 64 InternetAddressType type: InternetAddressType.ANY}) { |
| 74 return _NativeSocket.listInterfaces( | 65 return _NativeSocket.listInterfaces(includeLoopback: includeLoopback, |
| 75 includeLoopback: includeLoopback, | 66 includeLinkLocal: includeLinkLocal, |
| 76 includeLinkLocal: includeLinkLocal, | 67 type: type); |
| 77 type: type); | |
| 78 } | 68 } |
| 79 | 69 |
| 80 static bool _listSupported() native "NetworkInterface_ListSupported"; | 70 static bool _listSupported() native "NetworkInterface_ListSupported"; |
| 81 } | 71 } |
| 82 | 72 |
| 83 void _throwOnBadPort(int port) { | 73 void _throwOnBadPort(int port) { |
| 84 if ((port == null) || (port < 0) || (port > 0xFFFF)) { | 74 if ((port == null) || (port < 0) || (port > 0xFFFF)) { |
| 85 throw new ArgumentError("Invalid port $port"); | 75 throw new ArgumentError("Invalid port $port"); |
| 86 } | 76 } |
| 87 } | 77 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 100 new _InternetAddress.fixed(_ADDRESS_LOOPBACK_IP_V6); | 90 new _InternetAddress.fixed(_ADDRESS_LOOPBACK_IP_V6); |
| 101 static _InternetAddress ANY_IP_V4 = | 91 static _InternetAddress ANY_IP_V4 = |
| 102 new _InternetAddress.fixed(_ADDRESS_ANY_IP_V4); | 92 new _InternetAddress.fixed(_ADDRESS_ANY_IP_V4); |
| 103 static _InternetAddress ANY_IP_V6 = | 93 static _InternetAddress ANY_IP_V6 = |
| 104 new _InternetAddress.fixed(_ADDRESS_ANY_IP_V6); | 94 new _InternetAddress.fixed(_ADDRESS_ANY_IP_V6); |
| 105 | 95 |
| 106 final String address; | 96 final String address; |
| 107 final String _host; | 97 final String _host; |
| 108 final Uint8List _in_addr; | 98 final Uint8List _in_addr; |
| 109 | 99 |
| 110 InternetAddressType get type => _in_addr.length == _IPV4_ADDR_LENGTH | 100 InternetAddressType get type => |
| 111 ? InternetAddressType.IP_V4 | 101 _in_addr.length == _IPV4_ADDR_LENGTH ? InternetAddressType.IP_V4 |
| 112 : InternetAddressType.IP_V6; | 102 : InternetAddressType.IP_V6; |
| 113 | 103 |
| 114 String get host => _host != null ? _host : address; | 104 String get host => _host != null ? _host : address; |
| 115 | 105 |
| 116 List<int> get rawAddress => new Uint8List.fromList(_in_addr); | 106 List<int> get rawAddress => new Uint8List.fromList(_in_addr); |
| 117 | 107 |
| 118 bool get isLoopback { | 108 bool get isLoopback { |
| 119 switch (type) { | 109 switch (type) { |
| 120 case InternetAddressType.IP_V4: | 110 case InternetAddressType.IP_V4: |
| 121 return _in_addr[0] == 127; | 111 return _in_addr[0] == 127; |
| 122 | 112 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 150 // Checking for ff00::/8. | 140 // Checking for ff00::/8. |
| 151 return _in_addr[0] == 0xFF; | 141 return _in_addr[0] == 0xFF; |
| 152 } | 142 } |
| 153 } | 143 } |
| 154 | 144 |
| 155 Future<InternetAddress> reverse() => _NativeSocket.reverseLookup(this); | 145 Future<InternetAddress> reverse() => _NativeSocket.reverseLookup(this); |
| 156 | 146 |
| 157 _InternetAddress(this.address, this._host, this._in_addr); | 147 _InternetAddress(this.address, this._host, this._in_addr); |
| 158 | 148 |
| 159 factory _InternetAddress.parse(String address) { | 149 factory _InternetAddress.parse(String address) { |
| 160 if (address is! String) { | 150 if (address is !String) { |
| 161 throw new ArgumentError("Invalid internet address $address"); | 151 throw new ArgumentError("Invalid internet address $address"); |
| 162 } | 152 } |
| 163 var in_addr = _parse(address); | 153 var in_addr = _parse(address); |
| 164 if (in_addr == null) { | 154 if (in_addr == null) { |
| 165 throw new ArgumentError("Invalid internet address $address"); | 155 throw new ArgumentError("Invalid internet address $address"); |
| 166 } | 156 } |
| 167 return new _InternetAddress(address, null, in_addr); | 157 return new _InternetAddress(address, null, in_addr); |
| 168 } | 158 } |
| 169 | 159 |
| 170 factory _InternetAddress.fixed(int id) { | 160 factory _InternetAddress.fixed(int id) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 final int index; | 216 final int index; |
| 227 final List<InternetAddress> addresses = []; | 217 final List<InternetAddress> addresses = []; |
| 228 | 218 |
| 229 _NetworkInterface(this.name, this.index); | 219 _NetworkInterface(this.name, this.index); |
| 230 | 220 |
| 231 String toString() { | 221 String toString() { |
| 232 return "NetworkInterface('$name', $addresses)"; | 222 return "NetworkInterface('$name', $addresses)"; |
| 233 } | 223 } |
| 234 } | 224 } |
| 235 | 225 |
| 226 |
| 236 // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing | 227 // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing |
| 237 // implicit constructor. | 228 // implicit constructor. |
| 238 class _NativeSocketNativeWrapper extends NativeFieldWrapperClass1 {} | 229 class _NativeSocketNativeWrapper extends NativeFieldWrapperClass1 {} |
| 239 | 230 |
| 231 |
| 240 // The _NativeSocket class encapsulates an OS socket. | 232 // The _NativeSocket class encapsulates an OS socket. |
| 241 class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { | 233 class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
| 242 // Bit flags used when communicating between the eventhandler and | 234 // Bit flags used when communicating between the eventhandler and |
| 243 // dart code. The EVENT flags are used to indicate events of | 235 // dart code. The EVENT flags are used to indicate events of |
| 244 // interest when sending a message from dart code to the | 236 // interest when sending a message from dart code to the |
| 245 // eventhandler. When receiving a message from the eventhandler the | 237 // eventhandler. When receiving a message from the eventhandler the |
| 246 // EVENT flags indicate the events that actually happened. The | 238 // EVENT flags indicate the events that actually happened. The |
| 247 // COMMAND flags are used to send commands from dart to the | 239 // COMMAND flags are used to send commands from dart to the |
| 248 // eventhandler. COMMAND flags are never received from the | 240 // eventhandler. COMMAND flags are never received from the |
| 249 // eventhandler. Additional flags are used to communicate other | 241 // eventhandler. Additional flags are used to communicate other |
| (...skipping 29 matching lines...) Expand all Loading... |
| 279 // Protocol flags. | 271 // Protocol flags. |
| 280 static const int TCP_SOCKET = 18; | 272 static const int TCP_SOCKET = 18; |
| 281 static const int UDP_SOCKET = 19; | 273 static const int UDP_SOCKET = 19; |
| 282 static const int INTERNAL_SOCKET = 20; | 274 static const int INTERNAL_SOCKET = 20; |
| 283 static const int TYPE_TCP_SOCKET = 1 << TCP_SOCKET; | 275 static const int TYPE_TCP_SOCKET = 1 << TCP_SOCKET; |
| 284 static const int TYPE_UDP_SOCKET = 1 << UDP_SOCKET; | 276 static const int TYPE_UDP_SOCKET = 1 << UDP_SOCKET; |
| 285 static const int TYPE_INTERNAL_SOCKET = 1 << INTERNAL_SOCKET; | 277 static const int TYPE_INTERNAL_SOCKET = 1 << INTERNAL_SOCKET; |
| 286 static const int TYPE_PROTOCOL_MASK = | 278 static const int TYPE_PROTOCOL_MASK = |
| 287 TYPE_TCP_SOCKET | TYPE_UDP_SOCKET | TYPE_INTERNAL_SOCKET; | 279 TYPE_TCP_SOCKET | TYPE_UDP_SOCKET | TYPE_INTERNAL_SOCKET; |
| 288 | 280 |
| 281 |
| 289 // Native port messages. | 282 // Native port messages. |
| 290 static const HOST_NAME_LOOKUP = 0; | 283 static const HOST_NAME_LOOKUP = 0; |
| 291 static const LIST_INTERFACES = 1; | 284 static const LIST_INTERFACES = 1; |
| 292 static const REVERSE_LOOKUP = 2; | 285 static const REVERSE_LOOKUP = 2; |
| 293 | 286 |
| 294 // Protocol flags. | 287 // Protocol flags. |
| 295 static const int PROTOCOL_IPV4 = 1 << 0; | 288 static const int PROTOCOL_IPV4 = 1 << 0; |
| 296 static const int PROTOCOL_IPV6 = 1 << 1; | 289 static const int PROTOCOL_IPV6 = 1 << 1; |
| 297 | 290 |
| 298 static const int NORMAL_TOKEN_BATCH_SIZE = 8; | 291 static const int NORMAL_TOKEN_BATCH_SIZE = 8; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 bool writeEventIssued = false; | 328 bool writeEventIssued = false; |
| 336 bool writeAvailable = false; | 329 bool writeAvailable = false; |
| 337 | 330 |
| 338 static bool connectedResourceHandler = false; | 331 static bool connectedResourceHandler = false; |
| 339 _ReadWriteResourceInfo resourceInfo; | 332 _ReadWriteResourceInfo resourceInfo; |
| 340 | 333 |
| 341 // The owner object is the object that the Socket is being used by, e.g. | 334 // The owner object is the object that the Socket is being used by, e.g. |
| 342 // a HttpServer, a WebSocket connection, a process pipe, etc. | 335 // a HttpServer, a WebSocket connection, a process pipe, etc. |
| 343 Object owner; | 336 Object owner; |
| 344 | 337 |
| 345 static Future<List<InternetAddress>> lookup(String host, | 338 static Future<List<InternetAddress>> lookup( |
| 346 {InternetAddressType type: InternetAddressType.ANY}) { | 339 String host, {InternetAddressType type: InternetAddressType.ANY}) { |
| 347 return _IOService | 340 return _IOService._dispatch(_SOCKET_LOOKUP, [host, type._value]) |
| 348 ._dispatch(_SOCKET_LOOKUP, [host, type._value]).then((response) { | 341 .then((response) { |
| 349 if (isErrorResponse(response)) { | 342 if (isErrorResponse(response)) { |
| 350 throw createError(response, "Failed host lookup: '$host'"); | 343 throw createError(response, "Failed host lookup: '$host'"); |
| 351 } else { | 344 } else { |
| 352 return response.skip(1).map((result) { | 345 return response.skip(1).map((result) { |
| 353 var type = new InternetAddressType._from(result[0]); | 346 var type = new InternetAddressType._from(result[0]); |
| 354 return new _InternetAddress(result[1], host, result[2]); | 347 return new _InternetAddress(result[1], host, result[2]); |
| 355 }).toList(); | 348 }).toList(); |
| 356 } | 349 } |
| 357 }); | 350 }); |
| 358 } | 351 } |
| 359 | 352 |
| 360 static Future<InternetAddress> reverseLookup(InternetAddress addr) { | 353 static Future<InternetAddress> reverseLookup(InternetAddress addr) { |
| 361 return _IOService | 354 return _IOService._dispatch(_SOCKET_REVERSE_LOOKUP, [addr._in_addr]) |
| 362 ._dispatch(_SOCKET_REVERSE_LOOKUP, [addr._in_addr]).then((response) { | 355 .then((response) { |
| 363 if (isErrorResponse(response)) { | 356 if (isErrorResponse(response)) { |
| 364 throw createError(response, "Failed reverse host lookup", addr); | 357 throw createError(response, "Failed reverse host lookup", addr); |
| 365 } else { | 358 } else { |
| 366 return addr._cloneWithNewHost(response); | 359 return addr._cloneWithNewHost(response); |
| 367 } | 360 } |
| 368 }); | 361 }); |
| 369 } | 362 } |
| 370 | 363 |
| 371 static Future<List<NetworkInterface>> listInterfaces( | 364 static Future<List<NetworkInterface>> listInterfaces({ |
| 372 {bool includeLoopback: false, | 365 bool includeLoopback: false, |
| 373 bool includeLinkLocal: false, | 366 bool includeLinkLocal: false, |
| 374 InternetAddressType type: InternetAddressType.ANY}) { | 367 InternetAddressType type: InternetAddressType.ANY}) { |
| 375 return _IOService | 368 return _IOService._dispatch(_SOCKET_LIST_INTERFACES, [type._value]) |
| 376 ._dispatch(_SOCKET_LIST_INTERFACES, [type._value]).then((response) { | 369 .then((response) { |
| 377 if (isErrorResponse(response)) { | 370 if (isErrorResponse(response)) { |
| 378 throw createError(response, "Failed listing interfaces"); | 371 throw createError(response, "Failed listing interfaces"); |
| 379 } else { | 372 } else { |
| 380 var map = response.skip(1).fold(new Map<String, NetworkInterface>(), | 373 var map = response.skip(1) |
| 381 (map, result) { | 374 .fold(new Map<String, NetworkInterface>(), (map, result) { |
| 382 var type = new InternetAddressType._from(result[0]); | 375 var type = new InternetAddressType._from(result[0]); |
| 383 var name = result[3]; | 376 var name = result[3]; |
| 384 var index = result[4]; | 377 var index = result[4]; |
| 385 var address = new _InternetAddress(result[1], "", result[2]); | 378 var address = new _InternetAddress(result[1], "", result[2]); |
| 386 if (!includeLinkLocal && address.isLinkLocal) return map; | 379 if (!includeLinkLocal && address.isLinkLocal) return map; |
| 387 if (!includeLoopback && address.isLoopback) return map; | 380 if (!includeLoopback && address.isLoopback) return map; |
| 388 map.putIfAbsent(name, () => new _NetworkInterface(name, index)); | 381 map.putIfAbsent( |
| 389 map[name].addresses.add(address); | 382 name, () => new _NetworkInterface(name, index)); |
| 390 return map; | 383 map[name].addresses.add(address); |
| 384 return map; |
| 385 }); |
| 386 return map.values.toList(); |
| 387 } |
| 391 }); | 388 }); |
| 392 return map.values.toList(); | |
| 393 } | |
| 394 }); | |
| 395 } | 389 } |
| 396 | 390 |
| 397 static Future<_NativeSocket> connect(host, int port, sourceAddress) { | 391 static Future<_NativeSocket> connect(host, int port, sourceAddress) { |
| 398 _throwOnBadPort(port); | 392 _throwOnBadPort(port); |
| 399 if (sourceAddress != null && sourceAddress is! _InternetAddress) { | 393 if (sourceAddress != null && sourceAddress is! _InternetAddress) { |
| 400 if (sourceAddress is String) { | 394 if (sourceAddress is String) { |
| 401 sourceAddress = new InternetAddress(sourceAddress); | 395 sourceAddress = new InternetAddress(sourceAddress); |
| 402 } | 396 } |
| 403 } | 397 } |
| 404 return new Future.value(host).then((host) { | 398 return new Future.value(host) |
| 405 if (host is _InternetAddress) return [host]; | 399 .then((host) { |
| 406 return lookup(host).then((addresses) { | 400 if (host is _InternetAddress) return [host]; |
| 407 if (addresses.isEmpty) { | 401 return lookup(host) |
| 408 throw createError(null, "Failed host lookup: '$host'"); | 402 .then((addresses) { |
| 409 } | 403 if (addresses.isEmpty) { |
| 410 return addresses; | 404 throw createError(null, "Failed host lookup: '$host'"); |
| 411 }); | 405 } |
| 412 }).then((addresses) { | 406 return addresses; |
| 413 assert(addresses is List); | 407 }); |
| 414 var completer = new Completer(); | 408 }) |
| 415 var it = addresses.iterator; | 409 .then((addresses) { |
| 416 var error = null; | 410 assert(addresses is List); |
| 417 var connecting = new HashMap(); | 411 var completer = new Completer(); |
| 418 void connectNext() { | 412 var it = addresses.iterator; |
| 419 if (!it.moveNext()) { | 413 var error = null; |
| 420 if (connecting.isEmpty) { | 414 var connecting = new HashMap(); |
| 421 assert(error != null); | 415 void connectNext() { |
| 422 completer.completeError(error); | 416 if (!it.moveNext()) { |
| 423 } | 417 if (connecting.isEmpty) { |
| 424 return; | 418 assert(error != null); |
| 425 } | 419 completer.completeError(error); |
| 426 var address = it.current; | 420 } |
| 427 var socket = new _NativeSocket.normal(); | 421 return; |
| 428 socket.localAddress = address; | 422 } |
| 429 var result; | 423 var address = it.current; |
| 430 if (sourceAddress == null) { | 424 var socket = new _NativeSocket.normal(); |
| 431 result = socket.nativeCreateConnect(address._in_addr, port); | 425 socket.localAddress = address; |
| 432 } else { | 426 var result; |
| 433 assert(sourceAddress is _InternetAddress); | 427 if (sourceAddress == null) { |
| 434 result = socket.nativeCreateBindConnect( | 428 result = socket.nativeCreateConnect(address._in_addr, port); |
| 435 address._in_addr, port, sourceAddress._in_addr); | |
| 436 } | |
| 437 if (result is OSError) { | |
| 438 // Keep first error, if present. | |
| 439 if (error == null) { | |
| 440 int errorCode = result.errorCode; | |
| 441 if (errorCode != null && socket.isBindError(errorCode)) { | |
| 442 error = createError(result, "Bind failed", sourceAddress); | |
| 443 } else { | 429 } else { |
| 444 error = createError(result, "Connection failed", address, port); | 430 assert(sourceAddress is _InternetAddress); |
| 431 result = socket.nativeCreateBindConnect( |
| 432 address._in_addr, port, sourceAddress._in_addr); |
| 433 } |
| 434 if (result is OSError) { |
| 435 // Keep first error, if present. |
| 436 if (error == null) { |
| 437 int errorCode = result.errorCode; |
| 438 if (errorCode != null && socket.isBindError(errorCode)) { |
| 439 error = createError(result, "Bind failed", sourceAddress); |
| 440 } else { |
| 441 error = |
| 442 createError(result, "Connection failed", address, port); |
| 443 } |
| 444 } |
| 445 connectNext(); |
| 446 } else { |
| 447 // Query the local port, for error messages. |
| 448 try { |
| 449 socket.port; |
| 450 } catch (e) { |
| 451 error = createError(e, "Connection failed", address, port); |
| 452 connectNext(); |
| 453 } |
| 454 // Set up timer for when we should retry the next address |
| 455 // (if any). |
| 456 var duration = address.isLoopback ? |
| 457 _RETRY_DURATION_LOOPBACK : |
| 458 _RETRY_DURATION; |
| 459 var timer = new Timer(duration, connectNext); |
| 460 setupResourceInfo(socket); |
| 461 |
| 462 connecting[socket] = timer; |
| 463 // Setup handlers for receiving the first write event which |
| 464 // indicate that the socket is fully connected. |
| 465 socket.setHandlers( |
| 466 write: () { |
| 467 timer.cancel(); |
| 468 socket.setListening(read: false, write: false); |
| 469 completer.complete(socket); |
| 470 connecting.remove(socket); |
| 471 connecting.forEach((s, t) { |
| 472 t.cancel(); |
| 473 s.close(); |
| 474 s.setHandlers(); |
| 475 s.setListening(read: false, write: false); |
| 476 }); |
| 477 }, |
| 478 error: (e) { |
| 479 timer.cancel(); |
| 480 socket.close(); |
| 481 // Keep first error, if present. |
| 482 if (error == null) error = e; |
| 483 connecting.remove(socket); |
| 484 if (connecting.isEmpty) connectNext(); |
| 485 }); |
| 486 socket.setListening(read: false, write: true); |
| 445 } | 487 } |
| 446 } | 488 } |
| 447 connectNext(); | 489 connectNext(); |
| 448 } else { | 490 return completer.future; |
| 449 // Query the local port, for error messages. | 491 }); |
| 450 try { | |
| 451 socket.port; | |
| 452 } catch (e) { | |
| 453 error = createError(e, "Connection failed", address, port); | |
| 454 connectNext(); | |
| 455 } | |
| 456 // Set up timer for when we should retry the next address | |
| 457 // (if any). | |
| 458 var duration = | |
| 459 address.isLoopback ? _RETRY_DURATION_LOOPBACK : _RETRY_DURATION; | |
| 460 var timer = new Timer(duration, connectNext); | |
| 461 setupResourceInfo(socket); | |
| 462 | |
| 463 connecting[socket] = timer; | |
| 464 // Setup handlers for receiving the first write event which | |
| 465 // indicate that the socket is fully connected. | |
| 466 socket.setHandlers(write: () { | |
| 467 timer.cancel(); | |
| 468 socket.setListening(read: false, write: false); | |
| 469 completer.complete(socket); | |
| 470 connecting.remove(socket); | |
| 471 connecting.forEach((s, t) { | |
| 472 t.cancel(); | |
| 473 s.close(); | |
| 474 s.setHandlers(); | |
| 475 s.setListening(read: false, write: false); | |
| 476 }); | |
| 477 }, error: (e) { | |
| 478 timer.cancel(); | |
| 479 socket.close(); | |
| 480 // Keep first error, if present. | |
| 481 if (error == null) error = e; | |
| 482 connecting.remove(socket); | |
| 483 if (connecting.isEmpty) connectNext(); | |
| 484 }); | |
| 485 socket.setListening(read: false, write: true); | |
| 486 } | |
| 487 } | |
| 488 | |
| 489 connectNext(); | |
| 490 return completer.future; | |
| 491 }); | |
| 492 } | 492 } |
| 493 | 493 |
| 494 static Future<_NativeSocket> bind( | 494 static Future<_NativeSocket> bind(host, |
| 495 host, int port, int backlog, bool v6Only, bool shared) { | 495 int port, |
| 496 int backlog, |
| 497 bool v6Only, |
| 498 bool shared) { |
| 496 _throwOnBadPort(port); | 499 _throwOnBadPort(port); |
| 497 return new Future.value(host).then((host) { | 500 return new Future.value(host) |
| 498 if (host is _InternetAddress) return host; | 501 .then((host) { |
| 499 return lookup(host).then((list) { | 502 if (host is _InternetAddress) return host; |
| 500 if (list.length == 0) { | 503 return lookup(host) |
| 501 throw createError(null, "Failed host lookup: '$host'"); | 504 .then((list) { |
| 502 } | 505 if (list.length == 0) { |
| 503 return list[0]; | 506 throw createError(null, "Failed host lookup: '$host'"); |
| 504 }); | 507 } |
| 505 }).then((address) { | 508 return list[0]; |
| 506 var socket = new _NativeSocket.listen(); | 509 }); |
| 507 socket.localAddress = address; | 510 }) |
| 508 var result = socket.nativeCreateBindListen( | 511 .then((address) { |
| 509 address._in_addr, port, backlog, v6Only, shared); | 512 var socket = new _NativeSocket.listen(); |
| 510 if (result is OSError) { | 513 socket.localAddress = address; |
| 511 throw new SocketException("Failed to create server socket", | 514 var result = socket.nativeCreateBindListen(address._in_addr, |
| 512 osError: result, address: address, port: port); | 515 port, |
| 513 } | 516 backlog, |
| 514 if (port != 0) socket.localPort = port; | 517 v6Only, |
| 515 setupResourceInfo(socket); | 518 shared); |
| 516 socket.connectToEventHandler(); | 519 if (result is OSError) { |
| 517 return socket; | 520 throw new SocketException("Failed to create server socket", |
| 518 }); | 521 osError: result, |
| 522 address: address, |
| 523 port: port); |
| 524 } |
| 525 if (port != 0) socket.localPort = port; |
| 526 setupResourceInfo(socket); |
| 527 socket.connectToEventHandler(); |
| 528 return socket; |
| 529 }); |
| 519 } | 530 } |
| 520 | 531 |
| 521 static void setupResourceInfo(_NativeSocket socket) { | 532 static void setupResourceInfo(_NativeSocket socket) { |
| 522 socket.resourceInfo = new _SocketResourceInfo(socket); | 533 socket.resourceInfo = new _SocketResourceInfo(socket); |
| 523 } | 534 } |
| 524 | 535 |
| 525 static Future<_NativeSocket> bindDatagram(host, int port, bool reuseAddress) { | 536 static Future<_NativeSocket> bindDatagram( |
| 537 host, int port, bool reuseAddress) { |
| 526 _throwOnBadPort(port); | 538 _throwOnBadPort(port); |
| 527 return new Future.value(host).then((host) { | 539 return new Future.value(host) |
| 528 if (host is _InternetAddress) return host; | 540 .then((host) { |
| 529 return lookup(host).then((list) { | 541 if (host is _InternetAddress) return host; |
| 530 if (list.length == 0) { | 542 return lookup(host) |
| 531 throw createError(null, "Failed host lookup: '$host'"); | 543 .then((list) { |
| 532 } | 544 if (list.length == 0) { |
| 533 return list[0]; | 545 throw createError(null, "Failed host lookup: '$host'"); |
| 534 }); | 546 } |
| 535 }).then((address) { | 547 return list[0]; |
| 536 var socket = new _NativeSocket.datagram(address); | 548 }); |
| 537 var result = | 549 }) |
| 538 socket.nativeCreateBindDatagram(address._in_addr, port, reuseAddress); | 550 .then((address) { |
| 539 if (result is OSError) { | 551 var socket = new _NativeSocket.datagram(address); |
| 540 throw new SocketException("Failed to create datagram socket", | 552 var result = socket.nativeCreateBindDatagram( |
| 541 osError: result, address: address, port: port); | 553 address._in_addr, port, reuseAddress); |
| 542 } | 554 if (result is OSError) { |
| 543 if (port != 0) socket.localPort = port; | 555 throw new SocketException("Failed to create datagram socket", |
| 544 setupResourceInfo(socket); | 556 osError: result, |
| 545 return socket; | 557 address: address, |
| 546 }); | 558 port: port); |
| 559 } |
| 560 if (port != 0) socket.localPort = port; |
| 561 setupResourceInfo(socket); |
| 562 return socket; |
| 563 }); |
| 547 } | 564 } |
| 548 | 565 |
| 549 _NativeSocket.datagram(this.localAddress) | 566 _NativeSocket.datagram(this.localAddress) |
| 550 : typeFlags = TYPE_NORMAL_SOCKET | TYPE_UDP_SOCKET; | 567 : typeFlags = TYPE_NORMAL_SOCKET | TYPE_UDP_SOCKET; |
| 551 | 568 |
| 552 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET | TYPE_TCP_SOCKET; | 569 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET | TYPE_TCP_SOCKET; |
| 553 | 570 |
| 554 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET | TYPE_TCP_SOCKET { | 571 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET | TYPE_TCP_SOCKET { |
| 555 isClosedWrite = true; | 572 isClosedWrite = true; |
| 556 } | 573 } |
| 557 | 574 |
| 558 _NativeSocket.pipe() : typeFlags = TYPE_PIPE; | 575 _NativeSocket.pipe() : typeFlags = TYPE_PIPE; |
| 559 | 576 |
| 560 _NativeSocket.watch(int id) | 577 _NativeSocket.watch(int id) |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 // Negate the result, as stated above. | 678 // Negate the result, as stated above. |
| 662 if (result < 0) result = -result; | 679 if (result < 0) result = -result; |
| 663 // TODO(ricow): Remove when we track internal and pipe uses. | 680 // TODO(ricow): Remove when we track internal and pipe uses. |
| 664 assert(resourceInfo != null || isPipe || isInternal); | 681 assert(resourceInfo != null || isPipe || isInternal); |
| 665 if (resourceInfo != null) { | 682 if (resourceInfo != null) { |
| 666 resourceInfo.addWrite(result); | 683 resourceInfo.addWrite(result); |
| 667 } | 684 } |
| 668 return result; | 685 return result; |
| 669 } | 686 } |
| 670 | 687 |
| 671 int send(List<int> buffer, int offset, int bytes, InternetAddress address, | 688 int send(List<int> buffer, int offset, int bytes, |
| 672 int port) { | 689 InternetAddress address, int port) { |
| 673 _throwOnBadPort(port); | 690 _throwOnBadPort(port); |
| 674 if (isClosing || isClosed) return 0; | 691 if (isClosing || isClosed) return 0; |
| 675 _BufferAndStart bufferAndStart = | 692 _BufferAndStart bufferAndStart = |
| 676 _ensureFastAndSerializableByteData(buffer, offset, bytes); | 693 _ensureFastAndSerializableByteData( |
| 677 var result = nativeSendTo(bufferAndStart.buffer, bufferAndStart.start, | 694 buffer, offset, bytes); |
| 678 bytes, address._in_addr, port); | 695 var result = nativeSendTo( |
| 696 bufferAndStart.buffer, bufferAndStart.start, bytes, |
| 697 address._in_addr, port); |
| 679 if (result is OSError) { | 698 if (result is OSError) { |
| 680 OSError osError = result; | 699 OSError osError = result; |
| 681 scheduleMicrotask(() => reportError(osError, "Send failed")); | 700 scheduleMicrotask(() => reportError(osError, "Send failed")); |
| 682 result = 0; | 701 result = 0; |
| 683 } | 702 } |
| 684 // TODO(ricow): Remove when we track internal and pipe uses. | 703 // TODO(ricow): Remove when we track internal and pipe uses. |
| 685 assert(resourceInfo != null || isPipe || isInternal); | 704 assert(resourceInfo != null || isPipe || isInternal); |
| 686 if (resourceInfo != null) { | 705 if (resourceInfo != null) { |
| 687 resourceInfo.addWrite(result); | 706 resourceInfo.addWrite(result); |
| 688 } | 707 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 handler(); | 772 handler(); |
| 754 } | 773 } |
| 755 return; | 774 return; |
| 756 } | 775 } |
| 757 var handler = eventHandlers[READ_EVENT]; | 776 var handler = eventHandlers[READ_EVENT]; |
| 758 if (handler == null) return; | 777 if (handler == null) return; |
| 759 readEventIssued = true; | 778 readEventIssued = true; |
| 760 handler(); | 779 handler(); |
| 761 scheduleMicrotask(issue); | 780 scheduleMicrotask(issue); |
| 762 } | 781 } |
| 763 | |
| 764 scheduleMicrotask(issue); | 782 scheduleMicrotask(issue); |
| 765 } | 783 } |
| 766 | 784 |
| 767 void issueWriteEvent({bool delayed: true}) { | 785 void issueWriteEvent({bool delayed: true}) { |
| 768 if (writeEventIssued) return; | 786 if (writeEventIssued) return; |
| 769 if (!writeAvailable) return; | 787 if (!writeAvailable) return; |
| 770 void issue() { | 788 void issue() { |
| 771 writeEventIssued = false; | 789 writeEventIssued = false; |
| 772 if (!writeAvailable) return; | 790 if (!writeAvailable) return; |
| 773 if (isClosing) return; | 791 if (isClosing) return; |
| 774 if (!sendWriteEvents) return; | 792 if (!sendWriteEvents) return; |
| 775 sendWriteEvents = false; | 793 sendWriteEvents = false; |
| 776 var handler = eventHandlers[WRITE_EVENT]; | 794 var handler = eventHandlers[WRITE_EVENT]; |
| 777 if (handler == null) return; | 795 if (handler == null) return; |
| 778 handler(); | 796 handler(); |
| 779 } | 797 } |
| 780 | |
| 781 if (delayed) { | 798 if (delayed) { |
| 782 writeEventIssued = true; | 799 writeEventIssued = true; |
| 783 scheduleMicrotask(issue); | 800 scheduleMicrotask(issue); |
| 784 } else { | 801 } else { |
| 785 issue(); | 802 issue(); |
| 786 } | 803 } |
| 787 } | 804 } |
| 788 | 805 |
| 789 // Multiplexes socket events to the socket handlers. | 806 // Multiplexes socket events to the socket handlers. |
| 790 void multiplex(int events) { | 807 void multiplex(int events) { |
| 791 for (int i = FIRST_EVENT; i <= LAST_EVENT; i++) { | 808 for (int i = FIRST_EVENT; i <= LAST_EVENT; i++) { |
| 792 if (((events & (1 << i)) != 0)) { | 809 if (((events & (1 << i)) != 0)) { |
| 793 if ((i == CLOSED_EVENT || i == READ_EVENT) && isClosedRead) continue; | 810 if ((i == CLOSED_EVENT || i == READ_EVENT) && isClosedRead) continue; |
| 794 if (isClosing && i != DESTROYED_EVENT) continue; | 811 if (isClosing && i != DESTROYED_EVENT) continue; |
| 795 if (i == CLOSED_EVENT && !isListening && !isClosing && !isClosed) { | 812 if (i == CLOSED_EVENT && |
| 813 !isListening && |
| 814 !isClosing && |
| 815 !isClosed) { |
| 796 isClosedRead = true; | 816 isClosedRead = true; |
| 797 issueReadEvent(); | 817 issueReadEvent(); |
| 798 continue; | 818 continue; |
| 799 } | 819 } |
| 800 | 820 |
| 801 if (i == WRITE_EVENT) { | 821 if (i == WRITE_EVENT) { |
| 802 writeAvailable = true; | 822 writeAvailable = true; |
| 803 issueWriteEvent(delayed: false); | 823 issueWriteEvent(delayed: false); |
| 804 continue; | 824 continue; |
| 805 } | 825 } |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 connectToEventHandler(); | 955 connectToEventHandler(); |
| 936 _EventHandler._sendData(this, eventPort.sendPort, fullData); | 956 _EventHandler._sendData(this, eventPort.sendPort, fullData); |
| 937 } | 957 } |
| 938 | 958 |
| 939 void connectToEventHandler() { | 959 void connectToEventHandler() { |
| 940 assert(!isClosed); | 960 assert(!isClosed); |
| 941 if (eventPort == null) { | 961 if (eventPort == null) { |
| 942 eventPort = new RawReceivePort(multiplex); | 962 eventPort = new RawReceivePort(multiplex); |
| 943 } | 963 } |
| 944 if (!connectedResourceHandler) { | 964 if (!connectedResourceHandler) { |
| 945 registerExtension( | 965 registerExtension('ext.dart.io.getOpenSockets', |
| 946 'ext.dart.io.getOpenSockets', _SocketResourceInfo.getOpenSockets); | 966 _SocketResourceInfo.getOpenSockets); |
| 947 registerExtension('ext.dart.io.getSocketByID', | 967 registerExtension('ext.dart.io.getSocketByID', |
| 948 _SocketResourceInfo.getSocketInfoMapByID); | 968 _SocketResourceInfo.getSocketInfoMapByID); |
| 949 | 969 |
| 950 connectedResourceHandler = true; | 970 connectedResourceHandler = true; |
| 951 } | 971 } |
| 952 } | 972 } |
| 953 | 973 |
| 954 void disconnectFromEventHandler() { | 974 void disconnectFromEventHandler() { |
| 955 assert(eventPort != null); | 975 assert(eventPort != null); |
| 956 eventPort.close(); | 976 eventPort.close(); |
| 957 eventPort = null; | 977 eventPort = null; |
| 958 // Now that we don't track this Socket anymore, we can clear the owner | 978 // Now that we don't track this Socket anymore, we can clear the owner |
| 959 // field. | 979 // field. |
| 960 owner = null; | 980 owner = null; |
| 961 } | 981 } |
| 962 | 982 |
| 963 // Check whether this is an error response from a native port call. | 983 // Check whether this is an error response from a native port call. |
| 964 static bool isErrorResponse(response) { | 984 static bool isErrorResponse(response) { |
| 965 return response is List && response[0] != _SUCCESS_RESPONSE; | 985 return response is List && response[0] != _SUCCESS_RESPONSE; |
| 966 } | 986 } |
| 967 | 987 |
| 968 // Create the appropriate error/exception from different returned | 988 // Create the appropriate error/exception from different returned |
| 969 // error objects. | 989 // error objects. |
| 970 static createError(error, String message, | 990 static createError(error, |
| 971 [InternetAddress address, int port]) { | 991 String message, |
| 992 [InternetAddress address, |
| 993 int port]) { |
| 972 if (error is OSError) { | 994 if (error is OSError) { |
| 973 return new SocketException(message, | 995 return new SocketException( |
| 974 osError: error, address: address, port: port); | 996 message, osError: error, address: address, port: port); |
| 975 } else if (error is List) { | 997 } else if (error is List) { |
| 976 assert(isErrorResponse(error)); | 998 assert(isErrorResponse(error)); |
| 977 switch (error[0]) { | 999 switch (error[0]) { |
| 978 case _ILLEGAL_ARGUMENT_RESPONSE: | 1000 case _ILLEGAL_ARGUMENT_RESPONSE: |
| 979 return new ArgumentError(); | 1001 return new ArgumentError(); |
| 980 case _OSERROR_RESPONSE: | 1002 case _OSERROR_RESPONSE: |
| 981 return new SocketException(message, | 1003 return new SocketException(message, |
| 982 osError: new OSError(error[2], error[1]), | 1004 osError: new OSError(error[2], error[1]), |
| 983 address: address, | 1005 address: address, |
| 984 port: port); | 1006 port: port); |
| 985 default: | 1007 default: |
| 986 return new Exception("Unknown error"); | 1008 return new Exception("Unknown error"); |
| 987 } | 1009 } |
| 988 } else { | 1010 } else { |
| 989 return new SocketException(message, address: address, port: port); | 1011 return new SocketException(message, address: address, port: port); |
| 990 } | 1012 } |
| 991 } | 1013 } |
| 992 | 1014 |
| 993 void reportError(error, String message) { | 1015 void reportError(error, String message) { |
| 994 var e = createError(error, message, address, localPort); | 1016 var e = createError(error, message, address, localPort); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 return InternetAddress.ANY_IP_V4; | 1055 return InternetAddress.ANY_IP_V4; |
| 1034 } | 1056 } |
| 1035 } else { | 1057 } else { |
| 1036 return null; | 1058 return null; |
| 1037 } | 1059 } |
| 1038 } | 1060 } |
| 1039 | 1061 |
| 1040 void joinMulticast(InternetAddress addr, NetworkInterface interface) { | 1062 void joinMulticast(InternetAddress addr, NetworkInterface interface) { |
| 1041 var interfaceAddr = multicastAddress(addr, interface); | 1063 var interfaceAddr = multicastAddress(addr, interface); |
| 1042 var interfaceIndex = interface == null ? 0 : interface.index; | 1064 var interfaceIndex = interface == null ? 0 : interface.index; |
| 1043 var result = nativeJoinMulticast(addr._in_addr, | 1065 var result = nativeJoinMulticast( |
| 1044 interfaceAddr == null ? null : interfaceAddr._in_addr, interfaceIndex); | 1066 addr._in_addr, |
| 1067 interfaceAddr == null ? null : interfaceAddr._in_addr, |
| 1068 interfaceIndex); |
| 1045 if (result is OSError) throw result; | 1069 if (result is OSError) throw result; |
| 1046 } | 1070 } |
| 1047 | 1071 |
| 1048 void leaveMulticast(InternetAddress addr, NetworkInterface interface) { | 1072 void leaveMulticast(InternetAddress addr, NetworkInterface interface) { |
| 1049 var interfaceAddr = multicastAddress(addr, interface); | 1073 var interfaceAddr = multicastAddress(addr, interface); |
| 1050 var interfaceIndex = interface == null ? 0 : interface.index; | 1074 var interfaceIndex = interface == null ? 0 : interface.index; |
| 1051 var result = nativeLeaveMulticast(addr._in_addr, | 1075 var result = nativeLeaveMulticast( |
| 1052 interfaceAddr == null ? null : interfaceAddr._in_addr, interfaceIndex); | 1076 addr._in_addr, |
| 1077 interfaceAddr == null ? null : interfaceAddr._in_addr, |
| 1078 interfaceIndex); |
| 1053 if (result is OSError) throw result; | 1079 if (result is OSError) throw result; |
| 1054 } | 1080 } |
| 1055 | 1081 |
| 1082 |
| 1056 void nativeSetSocketId(int id) native "Socket_SetSocketId"; | 1083 void nativeSetSocketId(int id) native "Socket_SetSocketId"; |
| 1057 nativeAvailable() native "Socket_Available"; | 1084 nativeAvailable() native "Socket_Available"; |
| 1058 nativeRead(int len) native "Socket_Read"; | 1085 nativeRead(int len) native "Socket_Read"; |
| 1059 nativeRecvFrom() native "Socket_RecvFrom"; | 1086 nativeRecvFrom() native "Socket_RecvFrom"; |
| 1060 nativeWrite(List<int> buffer, int offset, int bytes) | 1087 nativeWrite(List<int> buffer, int offset, int bytes) |
| 1061 native "Socket_WriteList"; | 1088 native "Socket_WriteList"; |
| 1062 nativeSendTo(List<int> buffer, int offset, int bytes, List<int> address, | 1089 nativeSendTo(List<int> buffer, int offset, int bytes, |
| 1063 int port) native "Socket_SendTo"; | 1090 List<int> address, int port) |
| 1064 nativeCreateConnect(List<int> addr, int port) native "Socket_CreateConnect"; | 1091 native "Socket_SendTo"; |
| 1065 nativeCreateBindConnect(List<int> addr, int port, List<int> sourceAddr) | 1092 nativeCreateConnect(List<int> addr, |
| 1093 int port) native "Socket_CreateConnect"; |
| 1094 nativeCreateBindConnect( |
| 1095 List<int> addr, int port, List<int> sourceAddr) |
| 1066 native "Socket_CreateBindConnect"; | 1096 native "Socket_CreateBindConnect"; |
| 1067 bool isBindError(int errorNumber) native "Socket_IsBindError"; | 1097 bool isBindError(int errorNumber) native "Socket_IsBindError"; |
| 1068 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only, | 1098 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only, |
| 1069 bool shared) native "ServerSocket_CreateBindListen"; | 1099 bool shared) |
| 1100 native "ServerSocket_CreateBindListen"; |
| 1070 nativeCreateBindDatagram(List<int> addr, int port, bool reuseAddress) | 1101 nativeCreateBindDatagram(List<int> addr, int port, bool reuseAddress) |
| 1071 native "Socket_CreateBindDatagram"; | 1102 native "Socket_CreateBindDatagram"; |
| 1072 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; | 1103 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; |
| 1073 int nativeGetPort() native "Socket_GetPort"; | 1104 int nativeGetPort() native "Socket_GetPort"; |
| 1074 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; | 1105 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; |
| 1075 int nativeGetSocketId() native "Socket_GetSocketId"; | 1106 int nativeGetSocketId() native "Socket_GetSocketId"; |
| 1076 OSError nativeGetError() native "Socket_GetError"; | 1107 OSError nativeGetError() native "Socket_GetError"; |
| 1077 nativeGetOption(int option, int protocol) native "Socket_GetOption"; | 1108 nativeGetOption(int option, int protocol) native "Socket_GetOption"; |
| 1078 bool nativeSetOption(int option, int protocol, value) | 1109 bool nativeSetOption(int option, int protocol, value) |
| 1079 native "Socket_SetOption"; | 1110 native "Socket_SetOption"; |
| 1080 OSError nativeJoinMulticast(List<int> addr, List<int> interfaceAddr, | 1111 OSError nativeJoinMulticast( |
| 1081 int interfaceIndex) native "Socket_JoinMulticast"; | 1112 List<int> addr, List<int> interfaceAddr, int interfaceIndex) |
| 1082 bool nativeLeaveMulticast(List<int> addr, List<int> interfaceAddr, | 1113 native "Socket_JoinMulticast"; |
| 1083 int interfaceIndex) native "Socket_LeaveMulticast"; | 1114 bool nativeLeaveMulticast( |
| 1115 List<int> addr, List<int> interfaceAddr, int interfaceIndex) |
| 1116 native "Socket_LeaveMulticast"; |
| 1084 } | 1117 } |
| 1085 | 1118 |
| 1086 class _RawServerSocket extends Stream<RawSocket> implements RawServerSocket { | 1119 |
| 1120 class _RawServerSocket extends Stream<RawSocket> |
| 1121 implements RawServerSocket { |
| 1087 final _NativeSocket _socket; | 1122 final _NativeSocket _socket; |
| 1088 StreamController<RawSocket> _controller; | 1123 StreamController<RawSocket> _controller; |
| 1089 ReceivePort _referencePort; | 1124 ReceivePort _referencePort; |
| 1090 bool _v6Only; | 1125 bool _v6Only; |
| 1091 | 1126 |
| 1092 static Future<_RawServerSocket> bind( | 1127 static Future<_RawServerSocket> bind(address, |
| 1093 address, int port, int backlog, bool v6Only, bool shared) { | 1128 int port, |
| 1129 int backlog, |
| 1130 bool v6Only, |
| 1131 bool shared) { |
| 1094 _throwOnBadPort(port); | 1132 _throwOnBadPort(port); |
| 1095 if (backlog < 0) throw new ArgumentError("Invalid backlog $backlog"); | 1133 if (backlog < 0) throw new ArgumentError("Invalid backlog $backlog"); |
| 1096 return _NativeSocket | 1134 return _NativeSocket.bind(address, port, backlog, v6Only, shared) |
| 1097 .bind(address, port, backlog, v6Only, shared) | |
| 1098 .then((socket) => new _RawServerSocket(socket, v6Only)); | 1135 .then((socket) => new _RawServerSocket(socket, v6Only)); |
| 1099 } | 1136 } |
| 1100 | 1137 |
| 1101 _RawServerSocket(this._socket, this._v6Only); | 1138 _RawServerSocket(this._socket, this._v6Only); |
| 1102 | 1139 |
| 1103 StreamSubscription<RawSocket> listen(void onData(RawSocket event), | 1140 StreamSubscription<RawSocket> listen(void onData(RawSocket event), |
| 1104 {Function onError, void onDone(), bool cancelOnError}) { | 1141 {Function onError, |
| 1142 void onDone(), |
| 1143 bool cancelOnError}) { |
| 1105 if (_controller != null) { | 1144 if (_controller != null) { |
| 1106 throw new StateError("Stream was already listened to"); | 1145 throw new StateError("Stream was already listened to"); |
| 1107 } | 1146 } |
| 1108 var zone = Zone.current; | 1147 var zone = Zone.current; |
| 1109 _controller = new StreamController( | 1148 _controller = new StreamController(sync: true, |
| 1110 sync: true, | |
| 1111 onListen: _onSubscriptionStateChange, | 1149 onListen: _onSubscriptionStateChange, |
| 1112 onCancel: _onSubscriptionStateChange, | 1150 onCancel: _onSubscriptionStateChange, |
| 1113 onPause: _onPauseStateChange, | 1151 onPause: _onPauseStateChange, |
| 1114 onResume: _onPauseStateChange); | 1152 onResume: _onPauseStateChange); |
| 1115 _socket.setHandlers(read: zone.bindCallback(() { | 1153 _socket.setHandlers( |
| 1116 while (_socket.available > 0) { | 1154 read: zone.bindCallback(() { |
| 1117 var socket = _socket.accept(); | 1155 while (_socket.available > 0) { |
| 1118 if (socket == null) return; | 1156 var socket = _socket.accept(); |
| 1119 _controller.add(new _RawSocket(socket)); | 1157 if (socket == null) return; |
| 1120 if (_controller.isPaused) return; | 1158 _controller.add(new _RawSocket(socket)); |
| 1121 } | 1159 if (_controller.isPaused) return; |
| 1122 }), error: zone.bindUnaryCallback((e) { | 1160 } |
| 1123 _controller.addError(e); | 1161 }), |
| 1124 _controller.close(); | 1162 error: zone.bindUnaryCallback((e) { |
| 1125 }), destroyed: () { | 1163 _controller.addError(e); |
| 1126 _controller.close(); | 1164 _controller.close(); |
| 1127 if (_referencePort != null) { | 1165 }), |
| 1128 _referencePort.close(); | 1166 destroyed: () { |
| 1129 _referencePort = null; | 1167 _controller.close(); |
| 1130 } | 1168 if (_referencePort != null) { |
| 1131 }); | 1169 _referencePort.close(); |
| 1132 return _controller.stream.listen(onData, | 1170 _referencePort = null; |
| 1133 onError: onError, onDone: onDone, cancelOnError: cancelOnError); | 1171 } |
| 1172 }); |
| 1173 return _controller.stream.listen( |
| 1174 onData, |
| 1175 onError: onError, |
| 1176 onDone: onDone, |
| 1177 cancelOnError: cancelOnError); |
| 1134 } | 1178 } |
| 1135 | 1179 |
| 1136 int get port => _socket.port; | 1180 int get port => _socket.port; |
| 1137 | 1181 |
| 1138 InternetAddress get address => _socket.address; | 1182 InternetAddress get address => _socket.address; |
| 1139 | 1183 |
| 1140 Future close() { | 1184 Future close() { |
| 1141 return _socket.close().then((_) { | 1185 return _socket.close().then((_) { |
| 1142 if (_referencePort != null) { | 1186 if (_referencePort != null) { |
| 1143 _referencePort.close(); | 1187 _referencePort.close(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1164 } | 1208 } |
| 1165 | 1209 |
| 1166 void _onPauseStateChange() { | 1210 void _onPauseStateChange() { |
| 1167 if (_controller.isPaused) { | 1211 if (_controller.isPaused) { |
| 1168 _pause(); | 1212 _pause(); |
| 1169 } else { | 1213 } else { |
| 1170 _resume(); | 1214 _resume(); |
| 1171 } | 1215 } |
| 1172 } | 1216 } |
| 1173 | 1217 |
| 1174 void set _owner(owner) { | 1218 void set _owner(owner) { _socket.owner = owner; } |
| 1175 _socket.owner = owner; | |
| 1176 } | |
| 1177 } | 1219 } |
| 1178 | 1220 |
| 1179 class _RawSocket extends Stream<RawSocketEvent> implements RawSocket { | 1221 |
| 1222 class _RawSocket extends Stream<RawSocketEvent> |
| 1223 implements RawSocket { |
| 1180 final _NativeSocket _socket; | 1224 final _NativeSocket _socket; |
| 1181 StreamController<RawSocketEvent> _controller; | 1225 StreamController<RawSocketEvent> _controller; |
| 1182 bool _readEventsEnabled = true; | 1226 bool _readEventsEnabled = true; |
| 1183 bool _writeEventsEnabled = true; | 1227 bool _writeEventsEnabled = true; |
| 1184 | 1228 |
| 1185 // Flag to handle Ctrl-D closing of stdio on Mac OS. | 1229 // Flag to handle Ctrl-D closing of stdio on Mac OS. |
| 1186 bool _isMacOSTerminalInput = false; | 1230 bool _isMacOSTerminalInput = false; |
| 1187 | 1231 |
| 1188 static Future<RawSocket> connect(host, int port, sourceAddress) { | 1232 static Future<RawSocket> connect(host, int port, sourceAddress) { |
| 1189 return _NativeSocket | 1233 return _NativeSocket.connect(host, port, sourceAddress) |
| 1190 .connect(host, port, sourceAddress) | |
| 1191 .then((socket) => new _RawSocket(socket)); | 1234 .then((socket) => new _RawSocket(socket)); |
| 1192 } | 1235 } |
| 1193 | 1236 |
| 1194 _RawSocket(this._socket) { | 1237 _RawSocket(this._socket) { |
| 1195 var zone = Zone.current; | 1238 var zone = Zone.current; |
| 1196 _controller = new StreamController( | 1239 _controller = new StreamController(sync: true, |
| 1197 sync: true, | |
| 1198 onListen: _onSubscriptionStateChange, | 1240 onListen: _onSubscriptionStateChange, |
| 1199 onCancel: _onSubscriptionStateChange, | 1241 onCancel: _onSubscriptionStateChange, |
| 1200 onPause: _onPauseStateChange, | 1242 onPause: _onPauseStateChange, |
| 1201 onResume: _onPauseStateChange); | 1243 onResume: _onPauseStateChange); |
| 1202 _socket.setHandlers( | 1244 _socket.setHandlers( |
| 1203 read: () => _controller.add(RawSocketEvent.READ), | 1245 read: () => _controller.add(RawSocketEvent.READ), |
| 1204 write: () { | 1246 write: () { |
| 1205 // The write event handler is automatically disabled by the | 1247 // The write event handler is automatically disabled by the |
| 1206 // event handler when it fires. | 1248 // event handler when it fires. |
| 1207 _writeEventsEnabled = false; | 1249 _writeEventsEnabled = false; |
| 1208 _controller.add(RawSocketEvent.WRITE); | 1250 _controller.add(RawSocketEvent.WRITE); |
| 1209 }, | 1251 }, |
| 1210 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), | 1252 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), |
| 1211 destroyed: () { | 1253 destroyed: () { |
| 1212 _controller.add(RawSocketEvent.CLOSED); | 1254 _controller.add(RawSocketEvent.CLOSED); |
| 1213 _controller.close(); | 1255 _controller.close(); |
| 1214 }, | 1256 }, |
| 1215 error: zone.bindUnaryCallback((e) { | 1257 error: zone.bindUnaryCallback((e) { |
| 1216 _controller.addError(e); | 1258 _controller.addError(e); |
| 1217 _socket.close(); | 1259 _socket.close(); |
| 1218 })); | 1260 }) |
| 1261 ); |
| 1219 } | 1262 } |
| 1220 | 1263 |
| 1221 factory _RawSocket._writePipe() { | 1264 factory _RawSocket._writePipe() { |
| 1222 var native = new _NativeSocket.pipe(); | 1265 var native = new _NativeSocket.pipe(); |
| 1223 native.isClosedRead = true; | 1266 native.isClosedRead = true; |
| 1224 native.closedReadEventSent = true; | 1267 native.closedReadEventSent = true; |
| 1225 return new _RawSocket(native); | 1268 return new _RawSocket(native); |
| 1226 } | 1269 } |
| 1227 | 1270 |
| 1228 factory _RawSocket._readPipe(int fd) { | 1271 factory _RawSocket._readPipe(int fd) { |
| 1229 var native = new _NativeSocket.pipe(); | 1272 var native = new _NativeSocket.pipe(); |
| 1230 native.isClosedWrite = true; | 1273 native.isClosedWrite = true; |
| 1231 if (fd != null) _getStdioHandle(native, fd); | 1274 if (fd != null) _getStdioHandle(native, fd); |
| 1232 var result = new _RawSocket(native); | 1275 var result = new _RawSocket(native); |
| 1233 if (fd != null) { | 1276 if (fd != null) { |
| 1234 var socketType = _StdIOUtils._nativeSocketType(result._socket); | 1277 var socketType = _StdIOUtils._nativeSocketType(result._socket); |
| 1235 result._isMacOSTerminalInput = | 1278 result._isMacOSTerminalInput = |
| 1236 Platform.isMacOS && socketType == _STDIO_HANDLE_TYPE_TERMINAL; | 1279 Platform.isMacOS && socketType == _STDIO_HANDLE_TYPE_TERMINAL; |
| 1237 } | 1280 } |
| 1238 return result; | 1281 return result; |
| 1239 } | 1282 } |
| 1240 | 1283 |
| 1241 StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event), | 1284 StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event), |
| 1242 {Function onError, void onDone(), bool cancelOnError}) { | 1285 {Function onError, |
| 1243 return _controller.stream.listen(onData, | 1286 void onDone(), |
| 1244 onError: onError, onDone: onDone, cancelOnError: cancelOnError); | 1287 bool cancelOnError}) { |
| 1288 return _controller.stream.listen( |
| 1289 onData, |
| 1290 onError: onError, |
| 1291 onDone: onDone, |
| 1292 cancelOnError: cancelOnError); |
| 1245 } | 1293 } |
| 1246 | 1294 |
| 1247 int available() => _socket.available; | 1295 int available() => _socket.available; |
| 1248 | 1296 |
| 1249 List<int> read([int len]) { | 1297 List<int> read([int len]) { |
| 1250 if (_isMacOSTerminalInput) { | 1298 if (_isMacOSTerminalInput) { |
| 1251 var available = this.available(); | 1299 var available = this.available(); |
| 1252 if (available == 0) return null; | 1300 if (available == 0) return null; |
| 1253 var data = _socket.read(len); | 1301 var data = _socket.read(len); |
| 1254 if (data == null || data.length < available) { | 1302 if (data == null || data.length < available) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1313 } | 1361 } |
| 1314 | 1362 |
| 1315 void _onSubscriptionStateChange() { | 1363 void _onSubscriptionStateChange() { |
| 1316 if (_controller.hasListener) { | 1364 if (_controller.hasListener) { |
| 1317 _resume(); | 1365 _resume(); |
| 1318 } else { | 1366 } else { |
| 1319 _socket.close(); | 1367 _socket.close(); |
| 1320 } | 1368 } |
| 1321 } | 1369 } |
| 1322 | 1370 |
| 1323 void set _owner(owner) { | 1371 void set _owner(owner) { _socket.owner = owner; } |
| 1324 _socket.owner = owner; | |
| 1325 } | |
| 1326 } | 1372 } |
| 1327 | 1373 |
| 1328 @patch | 1374 |
| 1329 class ServerSocket { | 1375 @patch class ServerSocket { |
| 1330 @patch | 1376 @patch static Future<ServerSocket> bind(address, |
| 1331 static Future<ServerSocket> bind(address, int port, | 1377 int port, |
| 1332 {int backlog: 0, bool v6Only: false, bool shared: false}) { | 1378 {int backlog: 0, |
| 1379 bool v6Only: false, |
| 1380 bool shared: false}) { |
| 1333 return _ServerSocket.bind(address, port, backlog, v6Only, shared); | 1381 return _ServerSocket.bind(address, port, backlog, v6Only, shared); |
| 1334 } | 1382 } |
| 1335 } | 1383 } |
| 1336 | 1384 |
| 1337 class _ServerSocket extends Stream<Socket> implements ServerSocket { | 1385 |
| 1386 class _ServerSocket extends Stream<Socket> |
| 1387 implements ServerSocket { |
| 1338 final _socket; | 1388 final _socket; |
| 1339 | 1389 |
| 1340 static Future<_ServerSocket> bind( | 1390 static Future<_ServerSocket> bind(address, |
| 1341 address, int port, int backlog, bool v6Only, bool shared) { | 1391 int port, |
| 1342 return _RawServerSocket | 1392 int backlog, |
| 1343 .bind(address, port, backlog, v6Only, shared) | 1393 bool v6Only, |
| 1394 bool shared) { |
| 1395 return _RawServerSocket.bind(address, port, backlog, v6Only, shared) |
| 1344 .then((socket) => new _ServerSocket(socket)); | 1396 .then((socket) => new _ServerSocket(socket)); |
| 1345 } | 1397 } |
| 1346 | 1398 |
| 1347 _ServerSocket(this._socket); | 1399 _ServerSocket(this._socket); |
| 1348 | 1400 |
| 1349 StreamSubscription<Socket> listen(void onData(Socket event), | 1401 StreamSubscription<Socket> listen(void onData(Socket event), |
| 1350 {Function onError, void onDone(), bool cancelOnError}) { | 1402 {Function onError, |
| 1351 return _socket.map((rawSocket) => new _Socket(rawSocket)).listen(onData, | 1403 void onDone(), |
| 1352 onError: onError, onDone: onDone, cancelOnError: cancelOnError); | 1404 bool cancelOnError}) { |
| 1405 return _socket.map((rawSocket) => new _Socket(rawSocket)).listen( |
| 1406 onData, |
| 1407 onError: onError, |
| 1408 onDone: onDone, |
| 1409 cancelOnError: cancelOnError); |
| 1353 } | 1410 } |
| 1354 | 1411 |
| 1355 int get port => _socket.port; | 1412 int get port => _socket.port; |
| 1356 | 1413 |
| 1357 InternetAddress get address => _socket.address; | 1414 InternetAddress get address => _socket.address; |
| 1358 | 1415 |
| 1359 Future close() => _socket.close().then((_) => this); | 1416 Future close() => _socket.close().then((_) => this); |
| 1360 | 1417 |
| 1361 void set _owner(owner) { | 1418 void set _owner(owner) { _socket._owner = owner; } |
| 1362 _socket._owner = owner; | 1419 } |
| 1420 |
| 1421 |
| 1422 @patch class Socket { |
| 1423 @patch static Future<Socket> connect(host, int port, {sourceAddress}) { |
| 1424 return RawSocket.connect(host, port, sourceAddress: sourceAddress).then( |
| 1425 (socket) => new _Socket(socket)); |
| 1363 } | 1426 } |
| 1364 } | 1427 } |
| 1365 | 1428 |
| 1366 @patch | |
| 1367 class Socket { | |
| 1368 @patch | |
| 1369 static Future<Socket> connect(host, int port, {sourceAddress}) { | |
| 1370 return RawSocket | |
| 1371 .connect(host, port, sourceAddress: sourceAddress) | |
| 1372 .then((socket) => new _Socket(socket)); | |
| 1373 } | |
| 1374 } | |
| 1375 | 1429 |
| 1376 class _SocketStreamConsumer extends StreamConsumer<List<int>> { | 1430 class _SocketStreamConsumer extends StreamConsumer<List<int>> { |
| 1377 StreamSubscription subscription; | 1431 StreamSubscription subscription; |
| 1378 final _Socket socket; | 1432 final _Socket socket; |
| 1379 int offset; | 1433 int offset; |
| 1380 List<int> buffer; | 1434 List<int> buffer; |
| 1381 bool paused = false; | 1435 bool paused = false; |
| 1382 Completer streamCompleter; | 1436 Completer streamCompleter; |
| 1383 | 1437 |
| 1384 _SocketStreamConsumer(this.socket); | 1438 _SocketStreamConsumer(this.socket); |
| 1385 | 1439 |
| 1386 Future<Socket> addStream(Stream<List<int>> stream) { | 1440 Future<Socket> addStream(Stream<List<int>> stream) { |
| 1387 socket._ensureRawSocketSubscription(); | 1441 socket._ensureRawSocketSubscription(); |
| 1388 streamCompleter = new Completer<Socket>(); | 1442 streamCompleter = new Completer<Socket>(); |
| 1389 if (socket._raw != null) { | 1443 if (socket._raw != null) { |
| 1390 subscription = stream.listen((data) { | 1444 subscription = stream.listen( |
| 1391 assert(!paused); | 1445 (data) { |
| 1392 assert(buffer == null); | 1446 assert(!paused); |
| 1393 buffer = data; | 1447 assert(buffer == null); |
| 1394 offset = 0; | 1448 buffer = data; |
| 1395 try { | 1449 offset = 0; |
| 1396 write(); | 1450 try { |
| 1397 } catch (e) { | 1451 write(); |
| 1398 socket.destroy(); | 1452 } catch (e) { |
| 1399 stop(); | 1453 socket.destroy(); |
| 1400 done(e); | 1454 stop(); |
| 1401 } | 1455 done(e); |
| 1402 }, onError: (error, [stackTrace]) { | 1456 } |
| 1403 socket.destroy(); | 1457 }, |
| 1404 done(error, stackTrace); | 1458 onError: (error, [stackTrace]) { |
| 1405 }, onDone: () { | 1459 socket.destroy(); |
| 1406 done(); | 1460 done(error, stackTrace); |
| 1407 }, cancelOnError: true); | 1461 }, |
| 1462 onDone: () { |
| 1463 done(); |
| 1464 }, |
| 1465 cancelOnError: true); |
| 1408 } | 1466 } |
| 1409 return streamCompleter.future; | 1467 return streamCompleter.future; |
| 1410 } | 1468 } |
| 1411 | 1469 |
| 1412 Future<Socket> close() { | 1470 Future<Socket> close() { |
| 1413 socket._consumerDone(); | 1471 socket._consumerDone(); |
| 1414 return new Future.value(socket); | 1472 return new Future.value(socket); |
| 1415 } | 1473 } |
| 1416 | 1474 |
| 1417 void write() { | 1475 void write() { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1447 | 1505 |
| 1448 void stop() { | 1506 void stop() { |
| 1449 if (subscription == null) return; | 1507 if (subscription == null) return; |
| 1450 subscription.cancel(); | 1508 subscription.cancel(); |
| 1451 subscription = null; | 1509 subscription = null; |
| 1452 paused = false; | 1510 paused = false; |
| 1453 socket._disableWriteEvent(); | 1511 socket._disableWriteEvent(); |
| 1454 } | 1512 } |
| 1455 } | 1513 } |
| 1456 | 1514 |
| 1515 |
| 1457 class _Socket extends Stream<List<int>> implements Socket { | 1516 class _Socket extends Stream<List<int>> implements Socket { |
| 1458 RawSocket _raw; // Set to null when the raw socket is closed. | 1517 RawSocket _raw; // Set to null when the raw socket is closed. |
| 1459 bool _closed = false; // Set to true when the raw socket is closed. | 1518 bool _closed = false; // Set to true when the raw socket is closed. |
| 1460 StreamController _controller; | 1519 StreamController _controller; |
| 1461 bool _controllerClosed = false; | 1520 bool _controllerClosed = false; |
| 1462 _SocketStreamConsumer _consumer; | 1521 _SocketStreamConsumer _consumer; |
| 1463 IOSink _sink; | 1522 IOSink _sink; |
| 1464 var _subscription; | 1523 var _subscription; |
| 1465 var _detachReady; | 1524 var _detachReady; |
| 1466 | 1525 |
| 1467 _Socket(this._raw) { | 1526 _Socket(this._raw) { |
| 1468 _controller = new StreamController<List<int>>( | 1527 _controller = new StreamController<List<int>>(sync: true, |
| 1469 sync: true, | |
| 1470 onListen: _onSubscriptionStateChange, | 1528 onListen: _onSubscriptionStateChange, |
| 1471 onCancel: _onSubscriptionStateChange, | 1529 onCancel: _onSubscriptionStateChange, |
| 1472 onPause: _onPauseStateChange, | 1530 onPause: _onPauseStateChange, |
| 1473 onResume: _onPauseStateChange); | 1531 onResume: _onPauseStateChange); |
| 1474 _consumer = new _SocketStreamConsumer(this); | 1532 _consumer = new _SocketStreamConsumer(this); |
| 1475 _sink = new IOSink(_consumer); | 1533 _sink = new IOSink(_consumer); |
| 1476 | 1534 |
| 1477 // Disable read events until there is a subscription. | 1535 // Disable read events until there is a subscription. |
| 1478 _raw.readEventsEnabled = false; | 1536 _raw.readEventsEnabled = false; |
| 1479 | 1537 |
| 1480 // Disable write events until the consumer needs it for pending writes. | 1538 // Disable write events until the consumer needs it for pending writes. |
| 1481 _raw.writeEventsEnabled = false; | 1539 _raw.writeEventsEnabled = false; |
| 1482 } | 1540 } |
| 1483 | 1541 |
| 1484 factory _Socket._writePipe() { | 1542 factory _Socket._writePipe() { |
| 1485 return new _Socket(new _RawSocket._writePipe()); | 1543 return new _Socket(new _RawSocket._writePipe()); |
| 1486 } | 1544 } |
| 1487 | 1545 |
| 1488 factory _Socket._readPipe([int fd]) { | 1546 factory _Socket._readPipe([int fd]) { |
| 1489 return new _Socket(new _RawSocket._readPipe(fd)); | 1547 return new _Socket(new _RawSocket._readPipe(fd)); |
| 1490 } | 1548 } |
| 1491 | 1549 |
| 1492 _NativeSocket get _nativeSocket => _raw._socket; | 1550 _NativeSocket get _nativeSocket => _raw._socket; |
| 1493 | 1551 |
| 1494 StreamSubscription<List<int>> listen(void onData(List<int> event), | 1552 StreamSubscription<List<int>> listen(void onData(List<int> event), |
| 1495 {Function onError, void onDone(), bool cancelOnError}) { | 1553 {Function onError, |
| 1496 return _controller.stream.listen(onData, | 1554 void onDone(), |
| 1497 onError: onError, onDone: onDone, cancelOnError: cancelOnError); | 1555 bool cancelOnError}) { |
| 1556 return _controller.stream.listen( |
| 1557 onData, |
| 1558 onError: onError, |
| 1559 onDone: onDone, |
| 1560 cancelOnError: cancelOnError); |
| 1498 } | 1561 } |
| 1499 | 1562 |
| 1500 Encoding get encoding => _sink.encoding; | 1563 Encoding get encoding => _sink.encoding; |
| 1501 | 1564 |
| 1502 void set encoding(Encoding value) { | 1565 void set encoding(Encoding value) { |
| 1503 _sink.encoding = value; | 1566 _sink.encoding = value; |
| 1504 } | 1567 } |
| 1505 | 1568 |
| 1506 void write(Object obj) => _sink.write(obj); | 1569 void write(Object obj) => _sink.write(obj); |
| 1507 | 1570 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1531 _controllerClosed = true; | 1594 _controllerClosed = true; |
| 1532 _controller.close(); | 1595 _controller.close(); |
| 1533 } | 1596 } |
| 1534 | 1597 |
| 1535 bool setOption(SocketOption option, bool enabled) { | 1598 bool setOption(SocketOption option, bool enabled) { |
| 1536 if (_raw == null) return false; | 1599 if (_raw == null) return false; |
| 1537 return _raw.setOption(option, enabled); | 1600 return _raw.setOption(option, enabled); |
| 1538 } | 1601 } |
| 1539 | 1602 |
| 1540 int get port { | 1603 int get port { |
| 1541 if (_raw == null) throw const SocketException.closed(); | 1604 if (_raw == null) throw const SocketException.closed();; |
| 1542 ; | |
| 1543 return _raw.port; | 1605 return _raw.port; |
| 1544 } | 1606 } |
| 1545 | 1607 |
| 1546 InternetAddress get address { | 1608 InternetAddress get address { |
| 1547 if (_raw == null) throw const SocketException.closed(); | 1609 if (_raw == null) throw const SocketException.closed();; |
| 1548 ; | |
| 1549 return _raw.address; | 1610 return _raw.address; |
| 1550 } | 1611 } |
| 1551 | 1612 |
| 1552 int get remotePort { | 1613 int get remotePort { |
| 1553 if (_raw == null) throw const SocketException.closed(); | 1614 if (_raw == null) throw const SocketException.closed();; |
| 1554 ; | |
| 1555 return _raw.remotePort; | 1615 return _raw.remotePort; |
| 1556 } | 1616 } |
| 1557 | 1617 |
| 1558 InternetAddress get remoteAddress { | 1618 InternetAddress get remoteAddress { |
| 1559 if (_raw == null) throw const SocketException.closed(); | 1619 if (_raw == null) throw const SocketException.closed();; |
| 1560 ; | |
| 1561 return _raw.remoteAddress; | 1620 return _raw.remoteAddress; |
| 1562 } | 1621 } |
| 1563 | 1622 |
| 1564 Future _detachRaw() { | 1623 Future _detachRaw() { |
| 1565 _detachReady = new Completer(); | 1624 _detachReady = new Completer(); |
| 1566 _sink.close(); | 1625 _sink.close(); |
| 1567 return _detachReady.future.then((_) { | 1626 return _detachReady.future.then((_) { |
| 1568 assert(_consumer.buffer == null); | 1627 assert(_consumer.buffer == null); |
| 1569 var raw = _raw; | 1628 var raw = _raw; |
| 1570 _raw = null; | 1629 _raw = null; |
| 1571 return [raw, _subscription]; | 1630 return [raw, _subscription]; |
| 1572 }); | 1631 }); |
| 1573 } | 1632 } |
| 1574 | 1633 |
| 1575 // Ensure a subscription on the raw socket. Both the stream and the | 1634 // Ensure a subscription on the raw socket. Both the stream and the |
| 1576 // consumer needs a subscription as they share the error and done | 1635 // consumer needs a subscription as they share the error and done |
| 1577 // events from the raw socket. | 1636 // events from the raw socket. |
| 1578 void _ensureRawSocketSubscription() { | 1637 void _ensureRawSocketSubscription() { |
| 1579 if (_subscription == null && _raw != null) { | 1638 if (_subscription == null && _raw != null) { |
| 1580 _subscription = _raw.listen(_onData, | 1639 _subscription = _raw.listen(_onData, |
| 1581 onError: _onError, onDone: _onDone, cancelOnError: true); | 1640 onError: _onError, |
| 1641 onDone: _onDone, |
| 1642 cancelOnError: true); |
| 1582 } | 1643 } |
| 1583 } | 1644 } |
| 1584 | 1645 |
| 1585 _closeRawSocket() { | 1646 _closeRawSocket() { |
| 1586 var tmp = _raw; | 1647 var tmp = _raw; |
| 1587 _raw = null; | 1648 _raw = null; |
| 1588 _closed = true; | 1649 _closed = true; |
| 1589 tmp.close(); | 1650 tmp.close(); |
| 1590 } | 1651 } |
| 1591 | 1652 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1660 if (_detachReady != null) { | 1721 if (_detachReady != null) { |
| 1661 _detachReady.complete(null); | 1722 _detachReady.complete(null); |
| 1662 } else { | 1723 } else { |
| 1663 if (_raw != null) { | 1724 if (_raw != null) { |
| 1664 _raw.shutdown(SocketDirection.SEND); | 1725 _raw.shutdown(SocketDirection.SEND); |
| 1665 _disableWriteEvent(); | 1726 _disableWriteEvent(); |
| 1666 } | 1727 } |
| 1667 } | 1728 } |
| 1668 } | 1729 } |
| 1669 | 1730 |
| 1670 void set _owner(owner) { | 1731 void set _owner(owner) { _raw._owner = owner; } |
| 1671 _raw._owner = owner; | |
| 1672 } | |
| 1673 } | 1732 } |
| 1674 | 1733 |
| 1675 @patch | 1734 |
| 1676 class RawDatagramSocket { | 1735 @patch class RawDatagramSocket { |
| 1677 @patch | 1736 @patch static Future<RawDatagramSocket> bind( |
| 1678 static Future<RawDatagramSocket> bind(host, int port, | 1737 host, int port, {bool reuseAddress: true}) { |
| 1679 {bool reuseAddress: true}) { | |
| 1680 return _RawDatagramSocket.bind(host, port, reuseAddress); | 1738 return _RawDatagramSocket.bind(host, port, reuseAddress); |
| 1681 } | 1739 } |
| 1682 } | 1740 } |
| 1683 | 1741 |
| 1684 class _RawDatagramSocket extends Stream implements RawDatagramSocket { | 1742 class _RawDatagramSocket extends Stream implements RawDatagramSocket { |
| 1685 _NativeSocket _socket; | 1743 _NativeSocket _socket; |
| 1686 StreamController<RawSocketEvent> _controller; | 1744 StreamController<RawSocketEvent> _controller; |
| 1687 bool _readEventsEnabled = true; | 1745 bool _readEventsEnabled = true; |
| 1688 bool _writeEventsEnabled = true; | 1746 bool _writeEventsEnabled = true; |
| 1689 | 1747 |
| 1690 _RawDatagramSocket(this._socket) { | 1748 _RawDatagramSocket(this._socket) { |
| 1691 var zone = Zone.current; | 1749 var zone = Zone.current; |
| 1692 _controller = new StreamController( | 1750 _controller = new StreamController(sync: true, |
| 1693 sync: true, | |
| 1694 onListen: _onSubscriptionStateChange, | 1751 onListen: _onSubscriptionStateChange, |
| 1695 onCancel: _onSubscriptionStateChange, | 1752 onCancel: _onSubscriptionStateChange, |
| 1696 onPause: _onPauseStateChange, | 1753 onPause: _onPauseStateChange, |
| 1697 onResume: _onPauseStateChange); | 1754 onResume: _onPauseStateChange); |
| 1698 _socket.setHandlers( | 1755 _socket.setHandlers( |
| 1699 read: () => _controller.add(RawSocketEvent.READ), | 1756 read: () => _controller.add(RawSocketEvent.READ), |
| 1700 write: () { | 1757 write: () { |
| 1701 // The write event handler is automatically disabled by the | 1758 // The write event handler is automatically disabled by the |
| 1702 // event handler when it fires. | 1759 // event handler when it fires. |
| 1703 _writeEventsEnabled = false; | 1760 _writeEventsEnabled = false; |
| 1704 _controller.add(RawSocketEvent.WRITE); | 1761 _controller.add(RawSocketEvent.WRITE); |
| 1705 }, | 1762 }, |
| 1706 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), | 1763 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), |
| 1707 destroyed: () { | 1764 destroyed: () { |
| 1708 _controller.add(RawSocketEvent.CLOSED); | 1765 _controller.add(RawSocketEvent.CLOSED); |
| 1709 _controller.close(); | 1766 _controller.close(); |
| 1710 }, | 1767 }, |
| 1711 error: zone.bindUnaryCallback((e) { | 1768 error: zone.bindUnaryCallback((e) { |
| 1712 _controller.addError(e); | 1769 _controller.addError(e); |
| 1713 _socket.close(); | 1770 _socket.close(); |
| 1714 })); | 1771 }) |
| 1772 ); |
| 1715 } | 1773 } |
| 1716 | 1774 |
| 1717 static Future<RawDatagramSocket> bind(host, int port, bool reuseAddress) { | 1775 static Future<RawDatagramSocket> bind( |
| 1776 host, int port, bool reuseAddress) { |
| 1718 _throwOnBadPort(port); | 1777 _throwOnBadPort(port); |
| 1719 return _NativeSocket | 1778 return _NativeSocket.bindDatagram(host, port, reuseAddress) |
| 1720 .bindDatagram(host, port, reuseAddress) | |
| 1721 .then((socket) => new _RawDatagramSocket(socket)); | 1779 .then((socket) => new _RawDatagramSocket(socket)); |
| 1722 } | 1780 } |
| 1723 | 1781 |
| 1724 StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event), | 1782 StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event), |
| 1725 {Function onError, void onDone(), bool cancelOnError}) { | 1783 {Function onError, |
| 1726 return _controller.stream.listen(onData, | 1784 void onDone(), |
| 1727 onError: onError, onDone: onDone, cancelOnError: cancelOnError); | 1785 bool cancelOnError}) { |
| 1786 return _controller.stream.listen( |
| 1787 onData, |
| 1788 onError: onError, |
| 1789 onDone: onDone, |
| 1790 cancelOnError: cancelOnError); |
| 1728 } | 1791 } |
| 1729 | 1792 |
| 1730 Future close() => _socket.close().then((_) => this); | 1793 Future close() => _socket.close().then((_) => this); |
| 1731 | 1794 |
| 1732 int send(List<int> buffer, InternetAddress address, int port) => | 1795 int send(List<int> buffer, InternetAddress address, int port) => |
| 1733 _socket.send(buffer, 0, buffer.length, address, port); | 1796 _socket.send(buffer, 0, buffer.length, address, port); |
| 1734 | 1797 |
| 1735 Datagram receive() { | 1798 Datagram receive() { |
| 1736 return _socket.receive(); | 1799 return _socket.receive(); |
| 1737 } | 1800 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1758 _writeEventsEnabled = value; | 1821 _writeEventsEnabled = value; |
| 1759 if (!_controller.isPaused) _resume(); | 1822 if (!_controller.isPaused) _resume(); |
| 1760 } | 1823 } |
| 1761 } | 1824 } |
| 1762 | 1825 |
| 1763 bool get multicastLoopback => | 1826 bool get multicastLoopback => |
| 1764 _socket.getOption(SocketOption._IP_MULTICAST_LOOP); | 1827 _socket.getOption(SocketOption._IP_MULTICAST_LOOP); |
| 1765 void set multicastLoopback(bool value) => | 1828 void set multicastLoopback(bool value) => |
| 1766 _socket.setOption(SocketOption._IP_MULTICAST_LOOP, value); | 1829 _socket.setOption(SocketOption._IP_MULTICAST_LOOP, value); |
| 1767 | 1830 |
| 1768 int get multicastHops => _socket.getOption(SocketOption._IP_MULTICAST_HOPS); | 1831 int get multicastHops => |
| 1832 _socket.getOption(SocketOption._IP_MULTICAST_HOPS); |
| 1769 void set multicastHops(int value) => | 1833 void set multicastHops(int value) => |
| 1770 _socket.setOption(SocketOption._IP_MULTICAST_HOPS, value); | 1834 _socket.setOption(SocketOption._IP_MULTICAST_HOPS, value); |
| 1771 | 1835 |
| 1772 NetworkInterface get multicastInterface => throw "Not implemented"; | 1836 NetworkInterface get multicastInterface => |
| 1837 throw "Not implemented"; |
| 1773 void set multicastInterface(NetworkInterface value) => | 1838 void set multicastInterface(NetworkInterface value) => |
| 1774 throw "Not implemented"; | 1839 throw "Not implemented"; |
| 1775 | 1840 |
| 1776 bool get broadcastEnabled => _socket.getOption(SocketOption._IP_BROADCAST); | 1841 bool get broadcastEnabled => |
| 1842 _socket.getOption(SocketOption._IP_BROADCAST); |
| 1777 void set broadcastEnabled(bool value) => | 1843 void set broadcastEnabled(bool value) => |
| 1778 _socket.setOption(SocketOption._IP_BROADCAST, value); | 1844 _socket.setOption(SocketOption._IP_BROADCAST, value); |
| 1779 | 1845 |
| 1780 int get port => _socket.port; | 1846 int get port => _socket.port; |
| 1781 | 1847 |
| 1782 InternetAddress get address => _socket.address; | 1848 InternetAddress get address => _socket.address; |
| 1783 | 1849 |
| 1784 _pause() { | 1850 _pause() { |
| 1785 _socket.setListening(read: false, write: false); | 1851 _socket.setListening(read: false, write: false); |
| 1786 } | 1852 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1799 | 1865 |
| 1800 void _onSubscriptionStateChange() { | 1866 void _onSubscriptionStateChange() { |
| 1801 if (_controller.hasListener) { | 1867 if (_controller.hasListener) { |
| 1802 _resume(); | 1868 _resume(); |
| 1803 } else { | 1869 } else { |
| 1804 _socket.close(); | 1870 _socket.close(); |
| 1805 } | 1871 } |
| 1806 } | 1872 } |
| 1807 } | 1873 } |
| 1808 | 1874 |
| 1809 Datagram _makeDatagram( | 1875 Datagram _makeDatagram(List<int> data, |
| 1810 List<int> data, String address, List<int> in_addr, int port) { | 1876 String address, |
| 1811 return new Datagram(data, new _InternetAddress(address, null, in_addr), port); | 1877 List<int> in_addr, |
| 1878 int port) { |
| 1879 return new Datagram( |
| 1880 data, |
| 1881 new _InternetAddress(address, null, in_addr), |
| 1882 port); |
| 1812 } | 1883 } |
| 1884 |
| OLD | NEW |