Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 758fb760 authored by Matthieu Baerts's avatar Matthieu Baerts Committed by Marvin W.
Browse files

MCS: fallback to port 443 if 5228 is blocked

According to Google Firebase's doc, other ports than 5228 can be used:

    If your organization has a firewall to restrict traffic to or from
    the Internet, you need to configure it to allow mobile devices to
    connect with FCM in order for devices on your network to receive
    messages. FCM typically uses port 5228, but it sometimes uses 443,
    5229, and 5230.

Src: https://firebase.google.com/docs/cloud-messaging/concept-options#messaging-ports-and-your-firewall

As suggested by @mar-v-in, it is enough to first try 5228 and then only
try with 443 as fall back port. Indeed, it would be surprising to find
any firewall blocking port 5228 but not 5229.

If none of these ports, a new attempt will be done later as before.

Closes: https://github.com/microg/GmsCore/issues/408


Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
parent 857ae818
Loading
Loading
Loading
Loading
+46 −29
Original line number Diff line number Diff line
@@ -123,7 +123,10 @@ public class McsService extends Service implements Handler.Callback {
    public static final String FROM_FIELD = "gcm@android.com";

    public static final String SERVICE_HOST = "mtalk.google.com";
    public static final int SERVICE_PORT = 5228;
    // A few ports are available: 443, 5228-5230 but also 5222-5223
    // See https://github.com/microg/GmsCore/issues/408
    // Likely if the main port 5228 is blocked by a firewall, the other 52xx are blocked as well
    public static final int[] SERVICE_PORTS = {5228, 443};

    private static final int WAKELOCK_TIMEOUT = 5000;
    // On bad mobile network a ping can take >60s, so we wait for an ACK for 90s
@@ -460,24 +463,14 @@ public class McsService extends Service implements Handler.Callback {
        }
    }

    private synchronized void connect() {
        try {
            closeAll();
            ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
            activeNetworkPref = GcmPrefs.get(this).getNetworkPrefForInfo(activeNetworkInfo);
            if (!GcmPrefs.get(this).isEnabledFor(activeNetworkInfo)) {
                logd(this, "Don't connect, because disabled for " + activeNetworkInfo.getTypeName());
                scheduleReconnect(this);
                return;
            }
            wasTornDown = false;
    private void connect(int port) throws Exception {
        this.wasTornDown = false;

            logd(this, "Starting MCS connection...");
            Socket socket = new Socket(SERVICE_HOST, SERVICE_PORT);
            logd(this, "Connected to " + SERVICE_HOST + ":" + SERVICE_PORT);
            sslSocket = SSLContext.getDefault().getSocketFactory().createSocket(socket, SERVICE_HOST, SERVICE_PORT, true);
            logd(this, "Activated SSL with " + SERVICE_HOST + ":" + SERVICE_PORT);
        logd(this, "Starting MCS connection to port " + port + "...");
        Socket socket = new Socket(SERVICE_HOST, port);
        logd(this, "Connected to " + SERVICE_HOST + ":" + port);
        sslSocket = SSLContext.getDefault().getSocketFactory().createSocket(socket, SERVICE_HOST, port, true);
        logd(this, "Activated SSL with " + SERVICE_HOST + ":" + port);
        inputStream = new McsInputStream(sslSocket.getInputStream(), rootHandler);
        outputStream = new McsOutputStream(sslSocket.getOutputStream(), rootHandler);
        inputStream.start();
@@ -488,10 +481,34 @@ public class McsService extends Service implements Handler.Callback {
        lastHeartbeatAckElapsedRealtime = SystemClock.elapsedRealtime();
        lastIncomingNetworkRealtime = SystemClock.elapsedRealtime();
        scheduleHeartbeat(this);
    }

    private synchronized void connect() {
        closeAll();

        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
        activeNetworkPref = GcmPrefs.get(this).getNetworkPrefForInfo(activeNetworkInfo);
        if (!GcmPrefs.get(this).isEnabledFor(activeNetworkInfo)) {
            logd(this, "Don't connect, because disabled for " + activeNetworkInfo.getTypeName());
            scheduleReconnect(this);
            return;
        }

        Exception exception = null;
        for (int port : SERVICE_PORTS) {
            try {
                connect(port);
                return;
            } catch (Exception e) {
            Log.w(TAG, "Exception while connecting!", e);
            rootHandler.sendMessage(rootHandler.obtainMessage(MSG_TEARDOWN, e));
                exception = e;
                Log.w(TAG, "Exception while connecting to " + SERVICE_HOST + ":" + port, e);
                closeAll();
            }
        }

        logd(this, "Unable to connect to all different ports, retrying later");
        rootHandler.sendMessage(rootHandler.obtainMessage(MSG_TEARDOWN, exception));
    }

    private void handleClose(Close close) {