Fix a bug where the PAC proxy port is not set correctly.

Test: new test for this behavior in the preliminary change
Test: FrameworksNetTests NetworkStackTests
Fixes: 138810051
Fixes: 140610528
Change-Id: I95a979d232fb60ece2e33e972bf5d66d20357a1f
This commit is contained in:
Aaron Huang
2021-06-08 13:11:45 +08:00
committed by Chalard Jean
parent 1eb19caf40
commit 9fe47bee09
4 changed files with 268 additions and 97 deletions

View File

@@ -34,6 +34,7 @@ import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
import static android.net.ConnectivityManager.CALLBACK_IP_CHANGED;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT;
@@ -548,7 +549,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
/**
* PAC manager has received new port.
*/
private static final int EVENT_PROXY_HAS_CHANGED = 16;
private static final int EVENT_PAC_PROXY_HAS_CHANGED = 16;
/**
* used internally when registering NetworkProviders
@@ -1322,7 +1323,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
public ProxyTracker makeProxyTracker(@NonNull Context context,
@NonNull Handler connServiceHandler) {
return new ProxyTracker(context, connServiceHandler, EVENT_PROXY_HAS_CHANGED);
return new ProxyTracker(context, connServiceHandler, EVENT_PAC_PROXY_HAS_CHANGED);
}
/**
@@ -1868,7 +1869,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@VisibleForTesting
void simulateUpdateProxyInfo(@Nullable final Network network,
@NonNull final ProxyInfo proxyInfo) {
Message.obtain(mHandler, EVENT_PROXY_HAS_CHANGED,
Message.obtain(mHandler, EVENT_PAC_PROXY_HAS_CHANGED,
new Pair<>(network, proxyInfo)).sendToTarget();
}
@@ -4654,6 +4655,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
rematchAllNetworksAndRequests();
mLingerMonitor.noteDisconnect(nai);
if (null == getDefaultNetwork() && nai.linkProperties.getHttpProxy() != null) {
// The obvious place to do this would be in makeDefault(), however makeDefault() is
// not called by the rematch in this case. This is because the code above unset
// this network from the default request's satisfier, and that is what the rematch
// is using as its source data to know what the old satisfier was. So as far as the
// rematch above is concerned, the old default network was null.
// Therefore if there is no new default, the default network was null and is still
// null, thus there was no change so makeDefault() is not called. So if the old
// network had a proxy and there is no new default, the proxy tracker should be told
// that there is no longer a default proxy.
// Strictly speaking this is not essential because having a proxy setting when
// there is no network is harmless, but it's still counter-intuitive so reset to null.
mProxyTracker.setDefaultProxy(null);
}
// Immediate teardown.
if (nai.teardownDelayMs == 0) {
destroyNetwork(nai);
@@ -5676,9 +5692,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
mProxyTracker.loadDeprecatedGlobalHttpProxy();
break;
}
case EVENT_PROXY_HAS_CHANGED: {
case EVENT_PAC_PROXY_HAS_CHANGED: {
final Pair<Network, ProxyInfo> arg = (Pair<Network, ProxyInfo>) msg.obj;
handleApplyDefaultProxy(arg.second);
handlePacProxyServiceStarted(arg.first, arg.second);
break;
}
case EVENT_REGISTER_NETWORK_PROVIDER: {
@@ -6133,12 +6149,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
return mProxyTracker.getGlobalProxy();
}
private void handleApplyDefaultProxy(@Nullable ProxyInfo proxy) {
if (proxy != null && TextUtils.isEmpty(proxy.getHost())
&& Uri.EMPTY.equals(proxy.getPacFileUrl())) {
proxy = null;
}
private void handlePacProxyServiceStarted(@Nullable Network net, @Nullable ProxyInfo proxy) {
mProxyTracker.setDefaultProxy(proxy);
final NetworkAgentInfo nai = getDefaultNetwork();
// TODO : this method should check that net == nai.network, unfortunately at this point
// 'net' is always null in practice (see PacProxyService#sendPacBroadcast). PAC proxy
// is only ever installed on the default network so in practice this is okay.
if (null == nai) return;
// PAC proxies only work on the default network. Therefore, only the default network
// should have its link properties fixed up for PAC proxies.
mProxyTracker.updateDefaultNetworkProxyPortForPAC(nai.linkProperties, nai.network);
if (nai.everConnected()) {
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_IP_CHANGED);
}
}
// If the proxy has changed from oldLp to newLp, resend proxy broadcast. This method gets called
@@ -7964,6 +7987,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// updateMtu(lp, null);
// }
if (isDefaultNetwork(networkAgent)) {
mProxyTracker.updateDefaultNetworkProxyPortForPAC(newLp, null);
updateTcpBufferSizes(newLp.getTcpBufferSizes());
}
@@ -7976,7 +8000,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mDnsManager.updatePrivateDnsStatus(netId, newLp);
if (isDefaultNetwork(networkAgent)) {
handleApplyDefaultProxy(newLp.getHttpProxy());
mProxyTracker.setDefaultProxy(newLp.getHttpProxy());
} else if (networkAgent.everConnected()) {
updateProxy(newLp, oldLp);
}
@@ -9023,6 +9047,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
private void resetHttpProxyForNonDefaultNetwork(NetworkAgentInfo oldDefaultNetwork) {
if (null == oldDefaultNetwork) return;
// The network stopped being the default. If it was using a PAC proxy, then the
// proxy needs to be reset, otherwise HTTP requests on this network may be sent
// to the local proxy server, which would forward them over the newly default network.
final ProxyInfo proxyInfo = oldDefaultNetwork.linkProperties.getHttpProxy();
if (null == proxyInfo || !proxyInfo.isPacProxy()) return;
oldDefaultNetwork.linkProperties.setHttpProxy(new ProxyInfo(proxyInfo.getPacFileUrl()));
notifyNetworkCallbacks(oldDefaultNetwork, CALLBACK_IP_CHANGED);
}
private void makeDefault(@NonNull final NetworkRequestInfo nri,
@Nullable final NetworkAgentInfo oldDefaultNetwork,
@Nullable final NetworkAgentInfo newDefaultNetwork) {
@@ -9048,8 +9083,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
mLingerMonitor.noteLingerDefaultNetwork(oldDefaultNetwork, newDefaultNetwork);
}
mNetworkActivityTracker.updateDataActivityTracking(newDefaultNetwork, oldDefaultNetwork);
handleApplyDefaultProxy(null != newDefaultNetwork
mProxyTracker.setDefaultProxy(null != newDefaultNetwork
? newDefaultNetwork.linkProperties.getHttpProxy() : null);
resetHttpProxyForNonDefaultNetwork(oldDefaultNetwork);
updateTcpBufferSizes(null != newDefaultNetwork
? newDefaultNetwork.linkProperties.getTcpBufferSizes() : null);
notifyIfacesChangedForNetworkStats();