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