Take a Network parameter to have an one-to-one mapping between keepalive and its underpinned network on the automatic keepalive. Existing design could not really tell which network should the automatic keepalive check for the TCP socket status if there are multiple automatic keepalives enabled, e.g. Bothe IWLAN and VPN on WiFi enable the automatic keepalive. The keepalive for IWLAN should check if there are any TCP sockets on the IWLAN network instead of VPN network. Bug: 259000745 Test: atest FrameworksNetTests Test: Cts in the follow up commit Change-Id: I7353f4ef43e8fdad02c4d4a0bb5f6efa7d94c1b4
104 lines
4.3 KiB
Java
104 lines
4.3 KiB
Java
/*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.net;
|
|
|
|
import android.annotation.NonNull;
|
|
import android.os.ParcelFileDescriptor;
|
|
import android.os.RemoteException;
|
|
import android.util.Log;
|
|
|
|
import java.net.InetAddress;
|
|
import java.util.concurrent.Executor;
|
|
|
|
/** @hide */
|
|
public final class NattSocketKeepalive extends SocketKeepalive {
|
|
/** The NAT-T destination port for IPsec */
|
|
public static final int NATT_PORT = 4500;
|
|
|
|
@NonNull private final InetAddress mSource;
|
|
@NonNull private final InetAddress mDestination;
|
|
private final int mResourceId;
|
|
|
|
public NattSocketKeepalive(@NonNull IConnectivityManager service,
|
|
@NonNull Network network,
|
|
@NonNull ParcelFileDescriptor pfd,
|
|
int resourceId,
|
|
@NonNull InetAddress source,
|
|
@NonNull InetAddress destination,
|
|
@NonNull Executor executor,
|
|
@NonNull Callback callback) {
|
|
super(service, network, pfd, executor, callback);
|
|
mSource = source;
|
|
mDestination = destination;
|
|
mResourceId = resourceId;
|
|
}
|
|
|
|
/**
|
|
* Request that keepalive be started with the given {@code intervalSec}.
|
|
*
|
|
* When a VPN is running with the network for this keepalive as its underlying network, the
|
|
* system can monitor the TCP connections on that VPN to determine whether this keepalive is
|
|
* necessary. To enable this behavior, pass {@link SocketKeepalive#FLAG_AUTOMATIC_ON_OFF} into
|
|
* the flags. When this is enabled, the system will disable sending keepalive packets when
|
|
* there are no TCP connections over the VPN(s) running over this network to save battery, and
|
|
* restart sending them as soon as any TCP connection is opened over one of the VPN networks.
|
|
* When no VPN is running on top of this network, this flag has no effect, i.e. the keepalives
|
|
* are always sent with the specified interval.
|
|
*
|
|
* Also {@see SocketKeepalive}.
|
|
*
|
|
* @param intervalSec The target interval in seconds between keepalive packet transmissions.
|
|
* The interval should be between 10 seconds and 3600 seconds. Otherwise,
|
|
* the supplied {@link Callback} will see a call to
|
|
* {@link Callback#onError(int)} with {@link #ERROR_INVALID_INTERVAL}.
|
|
* @param flags Flags to enable/disable available options on this keepalive.
|
|
* @param underpinnedNetwork The underpinned network of this keepalive.
|
|
*
|
|
* @hide
|
|
*/
|
|
@Override
|
|
protected void startImpl(int intervalSec, int flags, Network underpinnedNetwork) {
|
|
if (0 != (flags & ~FLAG_AUTOMATIC_ON_OFF)) {
|
|
throw new IllegalArgumentException("Illegal flag value for "
|
|
+ this.getClass().getSimpleName() + " : " + flags);
|
|
}
|
|
final boolean automaticOnOffKeepalives = 0 != (flags & FLAG_AUTOMATIC_ON_OFF);
|
|
mExecutor.execute(() -> {
|
|
try {
|
|
mService.startNattKeepaliveWithFd(mNetwork, mPfd, mResourceId,
|
|
intervalSec, mCallback, mSource.getHostAddress(),
|
|
mDestination.getHostAddress(), automaticOnOffKeepalives,
|
|
underpinnedNetwork);
|
|
} catch (RemoteException e) {
|
|
Log.e(TAG, "Error starting socket keepalive: ", e);
|
|
throw e.rethrowFromSystemServer();
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
protected void stopImpl() {
|
|
mExecutor.execute(() -> {
|
|
try {
|
|
mService.stopKeepalive(mCallback);
|
|
} catch (RemoteException e) {
|
|
Log.e(TAG, "Error stopping socket keepalive: ", e);
|
|
throw e.rethrowFromSystemServer();
|
|
}
|
|
});
|
|
}
|
|
}
|