Unverified Commit a4fa61b4 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Use ephemeral ports for iOS port forwarding (#60381)

parent 025463f4
......@@ -14,6 +14,7 @@ import '../artifacts.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../base/utils.dart';
......@@ -493,6 +494,7 @@ class IOSDevice extends Device {
dyLdLibEntry: globals.cache.dyLdLibEntry,
id: id,
iproxyPath: _iproxyPath,
operatingSystemUtils: globals.os,
);
@visibleForTesting
......@@ -763,11 +765,13 @@ class IOSDevicePortForwarder extends DevicePortForwarder {
@required MapEntry<String, String> dyLdLibEntry,
@required String id,
@required String iproxyPath,
@required OperatingSystemUtils operatingSystemUtils,
}) : _logger = logger,
_dyLdLibEntry = dyLdLibEntry,
_id = id,
_iproxyPath = iproxyPath,
_processUtils = ProcessUtils(processManager: processManager, logger: logger);
_processUtils = ProcessUtils(processManager: processManager, logger: logger),
_operatingSystemUtils = operatingSystemUtils;
/// Create a [IOSDevicePortForwarder] for testing.
///
......@@ -779,6 +783,7 @@ class IOSDevicePortForwarder extends DevicePortForwarder {
@required ProcessManager processManager,
@required Logger logger,
String id,
OperatingSystemUtils operatingSystemUtils,
}) {
return IOSDevicePortForwarder(
processManager: processManager,
......@@ -788,6 +793,7 @@ class IOSDevicePortForwarder extends DevicePortForwarder {
dyLdLibEntry: const MapEntry<String, String>(
'DYLD_LIBRARY_PATH', '/path/to/libs',
),
operatingSystemUtils: operatingSystemUtils,
);
}
......@@ -796,6 +802,7 @@ class IOSDevicePortForwarder extends DevicePortForwarder {
final MapEntry<String, String> _dyLdLibEntry;
final String _id;
final String _iproxyPath;
final OperatingSystemUtils _operatingSystemUtils;
@override
List<ForwardedPort> forwardedPorts = <ForwardedPort>[];
......@@ -811,7 +818,9 @@ class IOSDevicePortForwarder extends DevicePortForwarder {
Future<int> forward(int devicePort, { int hostPort }) async {
final bool autoselect = hostPort == null || hostPort == 0;
if (autoselect) {
hostPort = 1024;
final int freePort = await _operatingSystemUtils?.findFreePort();
// Dynamic port range 49152 - 65535.
hostPort = freePort == null || freePort == 0 ? 49152 : freePort;
}
Process process;
......
......@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
......@@ -226,6 +227,12 @@ void main() {
iproxyPath: mockArtifacts.getArtifactPath(Artifact.iproxy, platform: TargetPlatform.ios),
logger: logger,
processManager: FakeProcessManager.any(),
operatingSystemUtils: OperatingSystemUtils(
fileSystem: mockFileSystem,
logger: logger,
platform: FakePlatform(operatingSystem: 'macos'),
processManager: FakeProcessManager.any(),
),
);
portForwarder.addForwardedPorts(<ForwardedPort>[forwardedPort]);
return portForwarder;
......
......@@ -3,7 +3,9 @@
// found in the LICENSE file.
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:mockito/mockito.dart';
import '../../src/common.dart';
import '../../src/context.dart';
......@@ -20,27 +22,33 @@ void main() {
const int devicePort = 456;
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
const FakeCommand(
command: <String>['iproxy', '1024', '456', '1234'],
command: <String>['iproxy', '49154', '456', '1234'],
// iproxy does not exit with 0 when it cannot forward.
exitCode: 0,
stdout: null, // no stdout indicates failure.
environment: kDyLdLibEntry,
),
const FakeCommand(
command: <String>['iproxy', '1025', '456', '1234'],
command: <String>['iproxy', '49155', '456', '1234'],
exitCode: 0,
stdout: 'not empty',
environment: kDyLdLibEntry,
),
]);
final MockOperatingSystemUtils operatingSystemUtils = MockOperatingSystemUtils();
when(operatingSystemUtils.findFreePort()).thenAnswer((Invocation invocation) => Future<int>.value(49154));
final IOSDevicePortForwarder portForwarder = IOSDevicePortForwarder.test(
processManager: processManager,
logger: BufferLogger.test(),
operatingSystemUtils: operatingSystemUtils,
);
final int hostPort = await portForwarder.forward(devicePort);
// First port tried (1024) should fail, then succeed on the next
expect(hostPort, 1024 + 1);
// First port tried (49154) should fail, then succeed on the next
expect(hostPort, 49154 + 1);
expect(processManager.hasRemainingExpectations, false);
});
}
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment