| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| // @dart = 2.9 |
| |
| import "dart:async"; |
| import "dart:io"; |
| import "package:expect/expect.dart"; |
| |
| RawServerSocket server; |
| RawSocket client; |
| |
| /// Creates a callback that listens for incomming connections. |
| /// If [remotePorts] is not null then callback would add remote port of each |
| /// new connection to the given list. |
| makeListener([List<int> remotePorts]) { |
| return (RawSocket serverSide) { |
| serveData(RawSocketEvent event) { |
| serverSide.shutdown(SocketDirection.send); |
| } |
| |
| remotePorts?.add(serverSide.remotePort); |
| serverSide.listen(serveData); |
| }; |
| } |
| |
| /// Verify that you can't connect to loopback via mismatching protocol, e.g. |
| /// if the server is listening to IPv4 then you can't connect via IPv6. |
| Future<void> failureTest( |
| InternetAddress serverAddr, InternetAddress clientAddr) async { |
| final remotePorts = <int>[]; |
| server = await RawServerSocket.bind(serverAddr, 0); |
| server.listen(makeListener(remotePorts)); |
| |
| bool success = false; |
| try { |
| client = await RawSocket.connect(clientAddr, server.port); |
| final clientPort = client.port; |
| |
| // We might actually succeed in connecting somewhere (e.g. to another test |
| // which by chance started listening to the same port). |
| // To make this test more robust we add a check that verifies that we did |
| // not connect to our server by checking if clientPort is within |
| // the list of remotePorts observed by the server. It should not be there. |
| await Future.delayed(Duration(seconds: 2)); |
| success = !remotePorts.contains(clientPort); |
| await client.close(); |
| } on SocketException catch (e) { |
| // We expect that we fail to connect to IPv4 server via IPv6 client and |
| // vice versa. |
| success = true; |
| } catch (e) { |
| Expect.fail('Unexpected exception: $e'); |
| } finally { |
| Expect.isTrue(success, |
| 'Unexpected connection to $serverAddr via $clientAddr address!'); |
| await server.close(); |
| } |
| } |
| |
| Future<void> successTest(InternetAddress address) async { |
| server = await RawServerSocket.bind(address, 0); |
| server.listen(makeListener()); |
| bool testFailure = false; |
| try { |
| client = await RawSocket.connect(address, server.port); |
| await client.close(); |
| } catch (e) { |
| testFailure = true; |
| } finally { |
| Expect.equals(testFailure, false); |
| await server.close(); |
| } |
| } |
| |
| main() async { |
| await failureTest(InternetAddress.loopbackIPv4, InternetAddress.loopbackIPv6); |
| await failureTest(InternetAddress.loopbackIPv6, InternetAddress.loopbackIPv4); |
| await successTest(InternetAddress.loopbackIPv4); |
| await successTest(InternetAddress.loopbackIPv6); |
| } |