Skip to content

Commit

Permalink
Work around Java emulators + WSL connectivity issues. (#2780)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuchenshi authored Nov 5, 2020
1 parent ef28371 commit bc882e2
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Work around Java emulators + WSL connectivity issues.
12 changes: 11 additions & 1 deletion src/emulator/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,20 @@ import { FLAG_EXPORT_ON_EXIT_NAME } from "./commandUtils";
import { fileExistsSync } from "../fsutils";

async function getAndCheckAddress(emulator: Emulators, options: any): Promise<Address> {
const host = Constants.normalizeHost(
let host = Constants.normalizeHost(
options.config.get(Constants.getHostKey(emulator), Constants.getDefaultHost(emulator))
);

if (host === "localhost" && utils.isRunningInWSL()) {
// HACK(https://github.com/firebase/firebase-tools-ui/issues/332): Use IPv4
// 127.0.0.1 instead of localhost. This, combined with the hack in
// downloadableEmulators.ts, forces the emulator to listen on IPv4 ONLY.
// The CLI (including the hub) will also consistently report 127.0.0.1,
// causing clients to connect via IPv4 only (which mitigates the problem of
// some clients resolving localhost to IPv6 and get connection refused).
host = "127.0.0.1";
}

const portVal = options.config.get(Constants.getPortKey(emulator), undefined);
let port;
let findAvailablePort = false;
Expand Down
14 changes: 14 additions & 0 deletions src/emulator/downloadableEmulators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,20 @@ function _getCommand(

const cmdLineArgs = baseCmd.args.slice();

if (
baseCmd.binary === "java" &&
utils.isRunningInWSL() &&
(!args.host || !args.host.includes(":"))
) {
// HACK(https://github.com/firebase/firebase-tools-ui/issues/332): Force
// Java to use IPv4 sockets in WSL (unless IPv6 address explicitly used).
// Otherwise, Java will open a tcp6 socket (even if IPv4 address is used),
// which handles both 4/6 on Linux but NOT IPv4 from the host to WSL.
// This is a hack because it breaks all IPv6 connections as a side effect.
// See: https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html
cmdLineArgs.unshift("-Djava.net.preferIPv4Stack=true"); // first argument
}

const logger = EmulatorLogger.forEmulator(emulator);
Object.keys(args).forEach((key) => {
if (!baseCmd.optionalArgs.includes(key)) {
Expand Down
8 changes: 8 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,3 +478,11 @@ export function datetimeString(d: Date): string {
export function isCloudEnvironment() {
return !!process.env.CODESPACES;
}

/**
* Indicates whether or not this process is likely to be running in WSL.
* @return true if we're likely in WSL, false otherwise
*/
export function isRunningInWSL(): boolean {
return !!process.env.WSL_DISTRO_NAME;
}

0 comments on commit bc882e2

Please sign in to comment.