Add TunnelInterface API and KernelResourceRecords

This change adds one KernelResourceRecord type (TunnelInterfaceRecord),
and adds methods for the creation of TunnelInterfaces, as well as the
application of Transforms to the given TunnelInterfaces

As part of the generation of ikeys/okeys, a ReserveKeyTracker manages a
java bitset to avoid collisions and reserve/release keys.

Bug: 63588681
Test: Compiles, CTS, unit tests all pass on AOSP_marlin
Change-Id: I9e9b6455e27073acd4491eae666aa966b3b10e0f
This commit is contained in:
Benedict Wong
2018-01-18 18:31:45 -08:00
parent 6b3456b253
commit 8bc907311b
5 changed files with 446 additions and 8 deletions

View File

@@ -21,6 +21,7 @@ import android.net.IpSecConfig;
import android.net.IpSecUdpEncapResponse;
import android.net.IpSecSpiResponse;
import android.net.IpSecTransformResponse;
import android.net.IpSecTunnelInterfaceResponse;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -39,11 +40,29 @@ interface IIpSecService
void closeUdpEncapsulationSocket(int resourceId);
IpSecTunnelInterfaceResponse createTunnelInterface(
in String localAddr,
in String remoteAddr,
in Network underlyingNetwork,
in IBinder binder);
void addAddressToTunnelInterface(
int tunnelResourceId,
String localAddr);
void removeAddressFromTunnelInterface(
int tunnelResourceId,
String localAddr);
void deleteTunnelInterface(int resourceId);
IpSecTransformResponse createTransform(in IpSecConfig c, in IBinder binder);
void deleteTransform(int transformId);
void applyTransportModeTransform(in ParcelFileDescriptor socket, int direction, int transformId);
void applyTunnelModeTransform(int tunnelResourceId, int direction, int transformResourceId);
void removeTransportModeTransforms(in ParcelFileDescriptor socket);
}

View File

@@ -685,7 +685,30 @@ public final class IpSecManager {
mLocalAddress = localAddress;
mRemoteAddress = remoteAddress;
mUnderlyingNetwork = underlyingNetwork;
// TODO: Call IpSecService
try {
IpSecTunnelInterfaceResponse result =
mService.createTunnelInterface(
localAddress.getHostAddress(),
remoteAddress.getHostAddress(),
underlyingNetwork,
new Binder());
switch (result.status) {
case Status.OK:
break;
case Status.RESOURCE_UNAVAILABLE:
throw new ResourceUnavailableException(
"No more tunnel interfaces may be allocated by this requester.");
default:
throw new RuntimeException(
"Unknown status returned by IpSecService: " + result.status);
}
mResourceId = result.resourceId;
mInterfaceName = result.interfaceName;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
mCloseGuard.open("constructor");
}
/**
@@ -697,12 +720,12 @@ public final class IpSecManager {
*/
@Override
public void close() {
// try {
// TODO: Call IpSecService
mResourceId = INVALID_RESOURCE_ID;
// } catch (RemoteException e) {
// throw e.rethrowFromSystemServer();
// }
try {
mService.deleteTunnelInterface(mResourceId);
mResourceId = INVALID_RESOURCE_ID;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
mCloseGuard.close();
}
@@ -714,11 +737,20 @@ public final class IpSecManager {
}
close();
}
/** @hide */
@VisibleForTesting
public int getResourceId() {
return mResourceId;
}
}
/**
* Create a new IpSecTunnelInterface as a local endpoint for tunneled IPsec traffic.
*
* <p>An application that creates tunnels is responsible for cleaning up the tunnel when the
* underlying network goes away, and the onLost() callback is received.
*
* @param localAddress The local addres of the tunnel
* @param remoteAddress The local addres of the tunnel
* @param underlyingNetwork the {@link Network} that will carry traffic for this tunnel.
@@ -750,7 +782,12 @@ public final class IpSecManager {
@SystemApi
public void applyTunnelModeTransform(IpSecTunnelInterface tunnel, int direction,
IpSecTransform transform) throws IOException {
// TODO: call IpSecService
try {
mService.applyTunnelModeTransform(
tunnel.getResourceId(), direction, transform.getResourceId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Construct an instance of IpSecManager within an application context.

View File

@@ -0,0 +1,20 @@
/*
* 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;
/** @hide */
parcelable IpSecTunnelInterfaceResponse;

View File

@@ -0,0 +1,78 @@
/*
* 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.os.Parcel;
import android.os.Parcelable;
/**
* This class is used to return an IpSecTunnelInterface resource Id and and corresponding status
* from the IpSecService to an IpSecTunnelInterface object.
*
* @hide
*/
public final class IpSecTunnelInterfaceResponse implements Parcelable {
private static final String TAG = "IpSecTunnelInterfaceResponse";
public final int resourceId;
public final String interfaceName;
public final int status;
// Parcelable Methods
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(status);
out.writeInt(resourceId);
out.writeString(interfaceName);
}
public IpSecTunnelInterfaceResponse(int inStatus) {
if (inStatus == IpSecManager.Status.OK) {
throw new IllegalArgumentException("Valid status implies other args must be provided");
}
status = inStatus;
resourceId = IpSecManager.INVALID_RESOURCE_ID;
interfaceName = "";
}
public IpSecTunnelInterfaceResponse(int inStatus, int inResourceId, String inInterfaceName) {
status = inStatus;
resourceId = inResourceId;
interfaceName = inInterfaceName;
}
private IpSecTunnelInterfaceResponse(Parcel in) {
status = in.readInt();
resourceId = in.readInt();
interfaceName = in.readString();
}
public static final Parcelable.Creator<IpSecTunnelInterfaceResponse> CREATOR =
new Parcelable.Creator<IpSecTunnelInterfaceResponse>() {
public IpSecTunnelInterfaceResponse createFromParcel(Parcel in) {
return new IpSecTunnelInterfaceResponse(in);
}
public IpSecTunnelInterfaceResponse[] newArray(int size) {
return new IpSecTunnelInterfaceResponse[size];
}
};
}