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

Commit 46208b52 authored by Danny Baumann's avatar Danny Baumann
Browse files

Fix DHCP not woking for routers that hand out very long leases.

As can be seen on
https://github.com/Quarx2k/android_device_motorola_umts_jordan/issues/209,
there are routers that hand out leases with extremely long lease times
(in that bug report: 180 years) instead of using 0xffffffff (infinite).
In those cases, the renewal timer calculations could overflow (as
DhcpInfo.leaseDuration is int), with the result becoming negative and
renewal being re-started because of that. The router ignored that
renewal (too short time inbetween requests), making the second DHCP
attempt fail.

Avoid that scenario by properly casting leaseDuration to long. Also
reduce code duplication to prevent making the same mistake twice ;-)
parent 5ed1fb17
Loading
Loading
Loading
Loading
+31 −23
Original line number Diff line number Diff line
@@ -2524,23 +2524,10 @@ public class WifiStateTracker extends NetworkStateTracker {
                    }

                    if (msg.what == EVENT_DHCP_START) {
                        Log.d(TAG, "DHCP request started");
                        if (NetworkUtils.runDhcp(mInterfaceName, mDhcpInfo)) {
                        if (runDhcp(false)) {
                            event = EVENT_INTERFACE_CONFIGURATION_SUCCEEDED;
                            Log.d(TAG, "DHCP succeeded with lease: " + mDhcpInfo.leaseDuration);
                            //Do it a bit earlier than half the lease duration time
                            //to beat the native DHCP client and avoid extra packets
                            //48% for one hour lease time = 29 minutes
                            //Don't do it if we're on an infinite lease
                            if (mDhcpInfo.leaseDuration >= 0) {
                                mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                        SystemClock.elapsedRealtime() +
                                        mDhcpInfo.leaseDuration * 480, //in milliseconds
                                        mDhcpRenewalIntent);
                            }
                        } else {
                            event = EVENT_INTERFACE_CONFIGURATION_FAILED;
                            Log.e(TAG, "DHCP request failed: " + NetworkUtils.getDhcpError());
                        }
                        synchronized (this) {
                            if (!mCancelCallback) {
@@ -2549,16 +2536,13 @@ public class WifiStateTracker extends NetworkStateTracker {
                        }

                    } else if (msg.what == EVENT_DHCP_RENEW) {
                        Log.d(TAG, "DHCP renewal started");
                        int oIp = mDhcpInfo.ipAddress;
                        int oGw = mDhcpInfo.gateway;
                        int oMsk = mDhcpInfo.netmask;
                        int oDns1 = mDhcpInfo.dns1;
                        int oDns2 = mDhcpInfo.dns2;

                        if (NetworkUtils.runDhcpRenew(mInterfaceName, mDhcpInfo)) {
                            Log.d(TAG, "DHCP renewal with lease: " + mDhcpInfo.leaseDuration);

                        if (runDhcp(true)) {
                            boolean changed =
                                (oIp   != mDhcpInfo.ipAddress ||
                                 oGw   != mDhcpInfo.gateway ||
@@ -2574,11 +2558,6 @@ public class WifiStateTracker extends NetworkStateTracker {
                                        mNetworkInfo);
                                msg.sendToTarget();
                            }

                            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                    SystemClock.elapsedRealtime() +
                                    mDhcpInfo.leaseDuration * 480,
                                    mDhcpRenewalIntent);
                        } else {
                            event = EVENT_INTERFACE_CONFIGURATION_FAILED;
                            Log.d(TAG, "DHCP renewal failed: " + NetworkUtils.getDhcpError());
@@ -2605,6 +2584,35 @@ public class WifiStateTracker extends NetworkStateTracker {
            }
        }

        private boolean runDhcp(boolean renew) {
            final String action = renew ? "DHCP request" : "DHCP renewal";

            Log.d(TAG, action + " started");

            boolean result = renew ? NetworkUtils.runDhcpRenew(mInterfaceName, mDhcpInfo) :
                                     NetworkUtils.runDhcp(mInterfaceName, mDhcpInfo);

            if (!result) {
                Log.e(TAG, action + " failed: " + NetworkUtils.getDhcpError());
                return false;
            }

            Log.d(TAG, action + " succeeded with lease: " + mDhcpInfo.leaseDuration);
            //Don't schedule renewal if we're on an infinite lease
            if (mDhcpInfo.leaseDuration >= 0) {
                //Do it a bit earlier than half the lease duration time
                //to beat the native DHCP client and avoid extra packets
                //48% for one hour lease time = 29 minutes
                long nextRenewal = (long) mDhcpInfo.leaseDuration * 480; // in milliseconds;
                nextRenewal += SystemClock.elapsedRealtime();

                mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                  nextRenewal, mDhcpRenewalIntent);
            }

            return true;
        }

        public synchronized void setCancelCallback(boolean cancelCallback) {
            mCancelCallback = cancelCallback;
            if (cancelCallback) {