a323c55162
Change-Id: I4d492a63a41880ef8cd69321372a4853825b9efd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426321 Reviewed-by: Liam Appelbe <liama@google.com> Auto-Submit: Bob Nystrom <rnystrom@google.com> Commit-Queue: Liam Appelbe <liama@google.com>
82 lines
2.7 KiB
Dart
82 lines
2.7 KiB
Dart
// 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.
|
|
|
|
import "dart:async";
|
|
import "dart:io";
|
|
import "package:expect/expect.dart";
|
|
|
|
/// Creates a callback that listens for incoming 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>[];
|
|
final server = await RawServerSocket.bind(serverAddr, 0);
|
|
server.listen(makeListener(remotePorts));
|
|
|
|
bool success = false;
|
|
try {
|
|
final 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 {
|
|
final server = await RawServerSocket.bind(address, 0);
|
|
server.listen(makeListener());
|
|
bool testFailure = false;
|
|
try {
|
|
final 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);
|
|
}
|