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 bool shared: false}) { | 10 bool shared: false}) { |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 RawReceivePort eventPort; | 296 RawReceivePort eventPort; |
297 bool flagsSent = false; | 297 bool flagsSent = false; |
298 | 298 |
299 // The type flags for this socket. | 299 // The type flags for this socket. |
300 final int typeFlags; | 300 final int typeFlags; |
301 | 301 |
302 // Holds the port of the socket, 0 if not known. | 302 // Holds the port of the socket, 0 if not known. |
303 int localPort = 0; | 303 int localPort = 0; |
304 | 304 |
305 // Holds the address used to connect or bind the socket. | 305 // Holds the address used to connect or bind the socket. |
306 InternetAddress localAddress; | 306 var /* InternetAddress or UnixDomainAddress */ localAddress; |
307 | 307 |
308 int available = 0; | 308 int available = 0; |
309 | 309 |
310 int tokens = 0; | 310 int tokens = 0; |
311 | 311 |
312 bool sendReadEvents = false; | 312 bool sendReadEvents = false; |
313 bool readEventIssued = false; | 313 bool readEventIssued = false; |
314 | 314 |
315 bool sendWriteEvents = false; | 315 bool sendWriteEvents = false; |
316 bool writeEventIssued = false; | 316 bool writeEventIssued = false; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 | 386 |
387 static Future<_NativeSocket> connect(host, int port, sourceAddress) { | 387 static Future<_NativeSocket> connect(host, int port, sourceAddress) { |
388 if (sourceAddress != null && sourceAddress is! _InternetAddress) { | 388 if (sourceAddress != null && sourceAddress is! _InternetAddress) { |
389 if (sourceAddress is String) { | 389 if (sourceAddress is String) { |
390 sourceAddress = new InternetAddress(sourceAddress); | 390 sourceAddress = new InternetAddress(sourceAddress); |
391 } | 391 } |
392 } | 392 } |
393 return new Future.value(host) | 393 return new Future.value(host) |
394 .then((host) { | 394 .then((host) { |
395 if (host is _InternetAddress) return [host]; | 395 if (host is _InternetAddress) return [host]; |
| 396 if (host is UnixDomainAddress) return [host]; |
396 return lookup(host) | 397 return lookup(host) |
397 .then((addresses) { | 398 .then((addresses) { |
398 if (addresses.isEmpty) { | 399 if (addresses.isEmpty) { |
399 throw createError(response, "Failed host lookup: '$host'"); | 400 throw createError(response, "Failed host lookup: '$host'"); |
400 } | 401 } |
401 return addresses; | 402 return addresses; |
402 }); | 403 }); |
403 }) | 404 }) |
404 .then((addresses) { | 405 .then((addresses) { |
405 assert(addresses is List); | 406 assert(addresses is List); |
406 var completer = new Completer(); | 407 var completer = new Completer(); |
407 var it = addresses.iterator; | 408 var it = addresses.iterator; |
408 var error = null; | 409 var error = null; |
409 var connecting = new HashMap(); | 410 var connecting = new HashMap(); |
410 void connectNext() { | 411 void connectNext() { |
411 if (!it.moveNext()) { | 412 if (!it.moveNext()) { |
412 if (connecting.isEmpty) { | 413 if (connecting.isEmpty) { |
413 assert(error != null); | 414 assert(error != null); |
414 completer.completeError(error); | 415 completer.completeError(error); |
415 } | 416 } |
416 return; | 417 return; |
417 } | 418 } |
418 var address = it.current; | 419 var address = it.current; |
419 var socket = new _NativeSocket.normal(); | 420 var socket = new _NativeSocket.normal(); |
420 socket.localAddress = address; | 421 socket.localAddress = address; |
421 var result; | 422 var result; |
422 if (sourceAddress == null) { | 423 if (sourceAddress == null) { |
423 result = socket.nativeCreateConnect(address._in_addr, port); | 424 if (address is UnixDomainAddress) { |
| 425 result = socket.nativeCreateConnectUnix(address.path); |
| 426 } else { |
| 427 result = socket.nativeCreateConnect(address._in_addr, port); |
| 428 } |
424 } else { | 429 } else { |
425 assert(sourceAddress is _InternetAddress); | 430 assert(sourceAddress is _InternetAddress); |
426 result = socket.nativeCreateBindConnect( | 431 result = socket.nativeCreateBindConnect( |
427 address._in_addr, port, sourceAddress._in_addr); | 432 address._in_addr, port, sourceAddress._in_addr); |
428 } | 433 } |
429 if (result is OSError) { | 434 if (result is OSError) { |
430 // Keep first error, if present. | 435 // Keep first error, if present. |
431 if (error == null) { | 436 if (error == null) { |
432 error = createError(result, "Connection failed", address, port); | 437 error = createError(result, "Connection failed", address, port); |
433 } | 438 } |
434 connectNext(); | 439 connectNext(); |
435 } else { | 440 } else { |
436 // Query the local port, for error messages. | 441 // Query the local port, for error messages. |
437 socket.port; | 442 if (address is !UnixDomainAddress) { |
| 443 socket.port; |
| 444 } |
438 // Set up timer for when we should retry the next address | 445 // Set up timer for when we should retry the next address |
439 // (if any). | 446 // (if any). |
440 var duration = address.isLoopback ? | 447 var duration = address.isLoopback ? |
441 _RETRY_DURATION_LOOPBACK : | 448 _RETRY_DURATION_LOOPBACK : |
442 _RETRY_DURATION; | 449 _RETRY_DURATION; |
443 var timer = new Timer(duration, connectNext); | 450 var timer = new Timer(duration, connectNext); |
444 connecting[socket] = timer; | 451 connecting[socket] = timer; |
445 // Setup handlers for receiving the first write event which | 452 // Setup handlers for receiving the first write event which |
446 // indicate that the socket is fully connected. | 453 // indicate that the socket is fully connected. |
447 socket.setHandlers( | 454 socket.setHandlers( |
(...skipping 26 matching lines...) Expand all Loading... |
474 } | 481 } |
475 | 482 |
476 static Future<_NativeSocket> bind(host, | 483 static Future<_NativeSocket> bind(host, |
477 int port, | 484 int port, |
478 int backlog, | 485 int backlog, |
479 bool v6Only, | 486 bool v6Only, |
480 bool shared) { | 487 bool shared) { |
481 return new Future.value(host) | 488 return new Future.value(host) |
482 .then((host) { | 489 .then((host) { |
483 if (host is _InternetAddress) return host; | 490 if (host is _InternetAddress) return host; |
| 491 if (host is UnixDomainAddress) return host; |
484 return lookup(host) | 492 return lookup(host) |
485 .then((list) { | 493 .then((list) { |
486 if (list.length == 0) { | 494 if (list.length == 0) { |
487 throw createError(response, "Failed host lookup: '$host'"); | 495 throw createError(response, "Failed host lookup: '$host'"); |
488 } | 496 } |
489 return list[0]; | 497 return list[0]; |
490 }); | 498 }); |
491 }) | 499 }) |
492 .then((address) { | 500 .then((address) { |
493 var socket = new _NativeSocket.listen(); | 501 var socket = new _NativeSocket.listen(); |
494 socket.localAddress = address; | 502 socket.localAddress = address; |
495 | 503 |
496 var result = socket.nativeCreateBindListen(address._in_addr, | 504 var result; |
497 port, | 505 if (host is UnixDomainAddress) { |
498 backlog, | 506 result = socket.nativeCreateBindListenUnix(host.path, |
499 v6Only, | 507 backlog, |
500 shared); | 508 shared); |
| 509 if (result is OSError) { |
| 510 throw new SocketException("Failed to create server socket", |
| 511 osError: result); |
| 512 } |
| 513 } else { |
| 514 result = socket.nativeCreateBindListen(address._in_addr, |
| 515 port, |
| 516 backlog, |
| 517 v6Only, |
| 518 shared); |
| 519 } |
| 520 |
501 if (result is OSError) { | 521 if (result is OSError) { |
502 throw new SocketException("Failed to create server socket", | 522 throw new SocketException("Failed to create server socket", |
503 osError: result, | 523 osError: result, |
504 address: address, | 524 address: address, |
505 port: port); | 525 port: port); |
506 } | 526 } |
507 if (port != 0) socket.localPort = port; | 527 if (port != 0) socket.localPort = port; |
508 socket.connectToEventHandler(); | 528 socket.connectToEventHandler(); |
509 return socket; | 529 return socket; |
510 }); | 530 }); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 return localPort = result; | 706 return localPort = result; |
687 } | 707 } |
688 | 708 |
689 int get remotePort { | 709 int get remotePort { |
690 if (isClosing || isClosed) throw const SocketException.closed(); | 710 if (isClosing || isClosed) throw const SocketException.closed(); |
691 var result = nativeGetRemotePeer(); | 711 var result = nativeGetRemotePeer(); |
692 if (result is OSError) throw result; | 712 if (result is OSError) throw result; |
693 return result[1]; | 713 return result[1]; |
694 } | 714 } |
695 | 715 |
696 InternetAddress get address => localAddress; | 716 /* InternetAddress or UnixDomainAddress */ get address => localAddress; |
697 | 717 |
698 InternetAddress get remoteAddress { | 718 InternetAddress get remoteAddress { |
699 if (isClosing || isClosed) throw const SocketException.closed(); | 719 if (isClosing || isClosed) throw const SocketException.closed(); |
700 var result = nativeGetRemotePeer(); | 720 var result = nativeGetRemotePeer(); |
701 if (result is OSError) throw result; | 721 if (result is OSError) throw result; |
702 var addr = result[0]; | 722 var addr = result[0]; |
703 var type = new InternetAddressType._from(addr[0]); | 723 // TODO(sgjesse): Type enum. |
704 return new _InternetAddress(addr[1], null, addr[2]); | 724 if (addr[0] == 2) { |
| 725 return new UnixDomainAddress(addr[1]); |
| 726 } else { |
| 727 var type = new InternetAddressType._from(addr[0]); |
| 728 return new _InternetAddress(addr[1], null, addr[2]); |
| 729 } |
705 } | 730 } |
706 | 731 |
707 void issueReadEvent() { | 732 void issueReadEvent() { |
708 if (closedReadEventSent) return; | 733 if (closedReadEventSent) return; |
709 if (readEventIssued) return; | 734 if (readEventIssued) return; |
710 readEventIssued = true; | 735 readEventIssued = true; |
711 void issue() { | 736 void issue() { |
712 readEventIssued = false; | 737 readEventIssued = false; |
713 if (isClosing) return; | 738 if (isClosing) return; |
714 if (!sendReadEvents) return; | 739 if (!sendReadEvents) return; |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 | 945 |
921 // Check whether this is an error response from a native port call. | 946 // Check whether this is an error response from a native port call. |
922 static bool isErrorResponse(response) { | 947 static bool isErrorResponse(response) { |
923 return response is List && response[0] != _SUCCESS_RESPONSE; | 948 return response is List && response[0] != _SUCCESS_RESPONSE; |
924 } | 949 } |
925 | 950 |
926 // Create the appropriate error/exception from different returned | 951 // Create the appropriate error/exception from different returned |
927 // error objects. | 952 // error objects. |
928 static createError(error, | 953 static createError(error, |
929 String message, | 954 String message, |
930 [InternetAddress address, | 955 [address, |
931 int port]) { | 956 int port]) { |
932 if (error is OSError) { | 957 if (error is OSError) { |
933 return new SocketException( | 958 return new SocketException( |
934 message, osError: error, address: address, port: port); | 959 message, osError: error, address: address, port: port); |
935 } else if (error is List) { | 960 } else if (error is List) { |
936 assert(isErrorResponse(error)); | 961 assert(isErrorResponse(error)); |
937 switch (error[0]) { | 962 switch (error[0]) { |
938 case _ILLEGAL_ARGUMENT_RESPONSE: | 963 case _ILLEGAL_ARGUMENT_RESPONSE: |
939 return new ArgumentError(); | 964 return new ArgumentError(); |
940 case _OSERROR_RESPONSE: | 965 case _OSERROR_RESPONSE: |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 nativeWrite(List<int> buffer, int offset, int bytes) | 1167 nativeWrite(List<int> buffer, int offset, int bytes) |
1143 native "Socket_WriteList"; | 1168 native "Socket_WriteList"; |
1144 nativeSendTo(List<int> buffer, int offset, int bytes, | 1169 nativeSendTo(List<int> buffer, int offset, int bytes, |
1145 List<int> address, int port) | 1170 List<int> address, int port) |
1146 native "Socket_SendTo"; | 1171 native "Socket_SendTo"; |
1147 nativeCreateConnect(List<int> addr, | 1172 nativeCreateConnect(List<int> addr, |
1148 int port) native "Socket_CreateConnect"; | 1173 int port) native "Socket_CreateConnect"; |
1149 nativeCreateBindConnect( | 1174 nativeCreateBindConnect( |
1150 List<int> addr, int port, List<int> sourceAddr) | 1175 List<int> addr, int port, List<int> sourceAddr) |
1151 native "Socket_CreateBindConnect"; | 1176 native "Socket_CreateBindConnect"; |
| 1177 nativeCreateConnectUnix(String path) native "Socket_CreateConnectUnix"; |
1152 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only, | 1178 nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only, |
1153 bool shared) | 1179 bool shared) |
1154 native "ServerSocket_CreateBindListen"; | 1180 native "ServerSocket_CreateBindListen"; |
| 1181 nativeCreateBindListenUnix(String addr, int backlog, bool shared) |
| 1182 native "ServerSocket_CreateBindListenUnix"; |
1155 nativeCreateBindDatagram(List<int> addr, int port, bool reuseAddress) | 1183 nativeCreateBindDatagram(List<int> addr, int port, bool reuseAddress) |
1156 native "Socket_CreateBindDatagram"; | 1184 native "Socket_CreateBindDatagram"; |
1157 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; | 1185 nativeAccept(_NativeSocket socket) native "ServerSocket_Accept"; |
1158 int nativeGetPort() native "Socket_GetPort"; | 1186 int nativeGetPort() native "Socket_GetPort"; |
1159 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; | 1187 List nativeGetRemotePeer() native "Socket_GetRemotePeer"; |
1160 int nativeGetSocketId() native "Socket_GetSocketId"; | 1188 int nativeGetSocketId() native "Socket_GetSocketId"; |
1161 OSError nativeGetError() native "Socket_GetError"; | 1189 OSError nativeGetError() native "Socket_GetError"; |
1162 nativeGetOption(int option, int protocol) native "Socket_GetOption"; | 1190 nativeGetOption(int option, int protocol) native "Socket_GetOption"; |
1163 bool nativeSetOption(int option, int protocol, value) | 1191 bool nativeSetOption(int option, int protocol, value) |
1164 native "Socket_SetOption"; | 1192 native "Socket_SetOption"; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 var zone = Zone.current; | 1232 var zone = Zone.current; |
1205 _controller = new StreamController(sync: true, | 1233 _controller = new StreamController(sync: true, |
1206 onListen: _onSubscriptionStateChange, | 1234 onListen: _onSubscriptionStateChange, |
1207 onCancel: _onSubscriptionStateChange, | 1235 onCancel: _onSubscriptionStateChange, |
1208 onPause: _onPauseStateChange, | 1236 onPause: _onPauseStateChange, |
1209 onResume: _onPauseStateChange); | 1237 onResume: _onPauseStateChange); |
1210 _socket.setHandlers( | 1238 _socket.setHandlers( |
1211 read: zone.bindCallback(() { | 1239 read: zone.bindCallback(() { |
1212 while (_socket.available > 0) { | 1240 while (_socket.available > 0) { |
1213 var socket = _socket.accept(); | 1241 var socket = _socket.accept(); |
1214 if (socket == null) return; | 1242 if (socket == null) { |
| 1243 return; |
| 1244 } |
1215 _controller.add(new _RawSocket(socket)); | 1245 _controller.add(new _RawSocket(socket)); |
1216 if (_controller.isPaused) return; | 1246 if (_controller.isPaused) return; |
1217 } | 1247 } |
1218 }), | 1248 }), |
1219 error: zone.bindUnaryCallback((e) { | 1249 error: zone.bindUnaryCallback((e) { |
1220 _controller.addError(e); | 1250 _controller.addError(e); |
1221 _controller.close(); | 1251 _controller.close(); |
1222 }), | 1252 }), |
1223 destroyed: () { | 1253 destroyed: () { |
1224 _controller.close(); | 1254 _controller.close(); |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1993 String address, | 2023 String address, |
1994 List<int> in_addr, | 2024 List<int> in_addr, |
1995 int port) { | 2025 int port) { |
1996 return new Datagram( | 2026 return new Datagram( |
1997 data, | 2027 data, |
1998 new _InternetAddress(address, null, in_addr), | 2028 new _InternetAddress(address, null, in_addr), |
1999 port); | 2029 port); |
2000 } | 2030 } |
2001 | 2031 |
2002 String _socketsStats() => _SocketsObservatory.toJSON(); | 2032 String _socketsStats() => _SocketsObservatory.toJSON(); |
OLD | NEW |