Add Initial IPsec APIs to IpSecService
-Plumb IpSecManager APIs to NetD -Add Resource Management to IpSecService Bug: 30984788 Test: b/34812052, b/34811227 Change-Id: Ic43965c6158f28cac53810adbf5cf50d2c54f920 (cherry picked from commit 93962f34ce21f5aac825afbcebf2f3e8c7a30910)
This commit is contained in:
@@ -16,9 +16,31 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.net.Network;
|
||||
import android.net.IpSecConfig;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
interface IIpSecService
|
||||
{
|
||||
Bundle reserveSecurityParameterIndex(
|
||||
int direction, in String remoteAddress, int requestedSpi, in IBinder binder);
|
||||
|
||||
void releaseSecurityParameterIndex(int resourceId);
|
||||
|
||||
Bundle openUdpEncapsulationSocket(int port, in IBinder binder);
|
||||
|
||||
void closeUdpEncapsulationSocket(in ParcelFileDescriptor socket);
|
||||
|
||||
Bundle createTransportModeTransform(in IpSecConfig c, in IBinder binder);
|
||||
|
||||
void deleteTransportModeTransform(int transformId);
|
||||
|
||||
void applyTransportModeTransform(in ParcelFileDescriptor socket, int transformId);
|
||||
|
||||
void removeTransportModeTransform(in ParcelFileDescriptor socket, int transformId);
|
||||
}
|
||||
|
||||
@@ -164,6 +164,8 @@ public final class IpSecAlgorithm implements Parcelable {
|
||||
|
||||
private static boolean isTruncationLengthValid(String algo, int truncLenBits) {
|
||||
switch (algo) {
|
||||
case ALGO_CRYPT_AES_CBC:
|
||||
return (truncLenBits == 128 || truncLenBits == 192 || truncLenBits == 256);
|
||||
case ALGO_AUTH_HMAC_MD5:
|
||||
return (truncLenBits >= 96 && truncLenBits <= 128);
|
||||
case ALGO_AUTH_HMAC_SHA1:
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.net.UnknownHostException;
|
||||
|
||||
/** @hide */
|
||||
public final class IpSecConfig implements Parcelable {
|
||||
private static final String TAG = IpSecConfig.class.getSimpleName();
|
||||
private static final String TAG = "IpSecConfig";
|
||||
|
||||
//MODE_TRANSPORT or MODE_TUNNEL
|
||||
int mode;
|
||||
@@ -43,13 +43,13 @@ public final class IpSecConfig implements Parcelable {
|
||||
int spi;
|
||||
|
||||
// Encryption Algorithm
|
||||
IpSecAlgorithm encryptionAlgo;
|
||||
IpSecAlgorithm encryption;
|
||||
|
||||
// Authentication Algorithm
|
||||
IpSecAlgorithm authenticationAlgo;
|
||||
IpSecAlgorithm authentication;
|
||||
}
|
||||
|
||||
Flow[] flow = new Flow[2];
|
||||
Flow[] flow = new Flow[] {new Flow(), new Flow()};
|
||||
|
||||
// For tunnel mode IPv4 UDP Encapsulation
|
||||
// IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE
|
||||
@@ -57,17 +57,15 @@ public final class IpSecConfig implements Parcelable {
|
||||
int encapLocalPort;
|
||||
int encapRemotePort;
|
||||
|
||||
// An optional protocol to match with the selector
|
||||
int selectorProto;
|
||||
|
||||
// A bitmask of FEATURE_* indicating which of the fields
|
||||
// of this class are valid.
|
||||
long features;
|
||||
|
||||
// An interval, in seconds between the NattKeepalive packets
|
||||
int nattKeepaliveInterval;
|
||||
|
||||
public InetAddress getLocalIp() {
|
||||
// Transport or Tunnel
|
||||
public int getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public InetAddress getLocalAddress() {
|
||||
return localAddress;
|
||||
}
|
||||
|
||||
@@ -75,19 +73,19 @@ public final class IpSecConfig implements Parcelable {
|
||||
return flow[direction].spi;
|
||||
}
|
||||
|
||||
public InetAddress getRemoteIp() {
|
||||
public InetAddress getRemoteAddress() {
|
||||
return remoteAddress;
|
||||
}
|
||||
|
||||
public IpSecAlgorithm getEncryptionAlgo(int direction) {
|
||||
return flow[direction].encryptionAlgo;
|
||||
public IpSecAlgorithm getEncryption(int direction) {
|
||||
return flow[direction].encryption;
|
||||
}
|
||||
|
||||
public IpSecAlgorithm getAuthenticationAlgo(int direction) {
|
||||
return flow[direction].authenticationAlgo;
|
||||
public IpSecAlgorithm getAuthentication(int direction) {
|
||||
return flow[direction].authentication;
|
||||
}
|
||||
|
||||
Network getNetwork() {
|
||||
public Network getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
@@ -103,18 +101,10 @@ public final class IpSecConfig implements Parcelable {
|
||||
return encapRemotePort;
|
||||
}
|
||||
|
||||
public int getSelectorProto() {
|
||||
return selectorProto;
|
||||
}
|
||||
|
||||
int getNattKeepaliveInterval() {
|
||||
public int getNattKeepaliveInterval() {
|
||||
return nattKeepaliveInterval;
|
||||
}
|
||||
|
||||
public boolean hasProperty(int featureBits) {
|
||||
return (features & featureBits) == featureBits;
|
||||
}
|
||||
|
||||
// Parcelable Methods
|
||||
|
||||
@Override
|
||||
@@ -124,31 +114,25 @@ public final class IpSecConfig implements Parcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeLong(features);
|
||||
// TODO: Use a byte array or other better method for storing IPs that can also include scope
|
||||
out.writeString((localAddress != null) ? localAddress.getHostAddress() : null);
|
||||
// TODO: Use a byte array or other better method for storing IPs that can also include scope
|
||||
out.writeString((remoteAddress != null) ? remoteAddress.getHostAddress() : null);
|
||||
out.writeParcelable(network, flags);
|
||||
out.writeInt(flow[IpSecTransform.DIRECTION_IN].spi);
|
||||
out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].encryptionAlgo, flags);
|
||||
out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].authenticationAlgo, flags);
|
||||
out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].encryption, flags);
|
||||
out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].authentication, flags);
|
||||
out.writeInt(flow[IpSecTransform.DIRECTION_OUT].spi);
|
||||
out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].encryptionAlgo, flags);
|
||||
out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].authenticationAlgo, flags);
|
||||
out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].encryption, flags);
|
||||
out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].authentication, flags);
|
||||
out.writeInt(encapType);
|
||||
out.writeInt(encapLocalPort);
|
||||
out.writeInt(encapRemotePort);
|
||||
out.writeInt(selectorProto);
|
||||
}
|
||||
|
||||
// Package Private: Used by the IpSecTransform.Builder;
|
||||
// there should be no public constructor for this object
|
||||
IpSecConfig() {
|
||||
flow[IpSecTransform.DIRECTION_IN].spi = 0;
|
||||
flow[IpSecTransform.DIRECTION_OUT].spi = 0;
|
||||
nattKeepaliveInterval = 0; //FIXME constant
|
||||
}
|
||||
IpSecConfig() {}
|
||||
|
||||
private static InetAddress readInetAddressFromParcel(Parcel in) {
|
||||
String addrString = in.readString();
|
||||
@@ -164,24 +148,22 @@ public final class IpSecConfig implements Parcelable {
|
||||
}
|
||||
|
||||
private IpSecConfig(Parcel in) {
|
||||
features = in.readLong();
|
||||
localAddress = readInetAddressFromParcel(in);
|
||||
remoteAddress = readInetAddressFromParcel(in);
|
||||
network = (Network) in.readParcelable(Network.class.getClassLoader());
|
||||
flow[IpSecTransform.DIRECTION_IN].spi = in.readInt();
|
||||
flow[IpSecTransform.DIRECTION_IN].encryptionAlgo =
|
||||
flow[IpSecTransform.DIRECTION_IN].encryption =
|
||||
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
|
||||
flow[IpSecTransform.DIRECTION_IN].authenticationAlgo =
|
||||
flow[IpSecTransform.DIRECTION_IN].authentication =
|
||||
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
|
||||
flow[IpSecTransform.DIRECTION_OUT].spi = in.readInt();
|
||||
flow[IpSecTransform.DIRECTION_OUT].encryptionAlgo =
|
||||
flow[IpSecTransform.DIRECTION_OUT].encryption =
|
||||
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
|
||||
flow[IpSecTransform.DIRECTION_OUT].authenticationAlgo =
|
||||
flow[IpSecTransform.DIRECTION_OUT].authentication =
|
||||
(IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
|
||||
encapType = in.readInt();
|
||||
encapLocalPort = in.readInt();
|
||||
encapRemotePort = in.readInt();
|
||||
selectorProto = in.readInt();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<IpSecConfig> CREATOR =
|
||||
|
||||
@@ -17,8 +17,11 @@ package android.net;
|
||||
|
||||
import static com.android.internal.util.Preconditions.checkNotNull;
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.util.AndroidException;
|
||||
import dalvik.system.CloseGuard;
|
||||
import java.io.FileDescriptor;
|
||||
@@ -38,6 +41,29 @@ import java.net.Socket;
|
||||
public final class IpSecManager {
|
||||
private static final String TAG = "IpSecManager";
|
||||
|
||||
/**
|
||||
* The Security Parameter Index, SPI, 0 indicates an unknown or invalid index.
|
||||
*
|
||||
* <p>No IPsec packet may contain an SPI of 0.
|
||||
*/
|
||||
public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
|
||||
|
||||
/** @hide */
|
||||
public interface Status {
|
||||
public static final int OK = 0;
|
||||
public static final int RESOURCE_UNAVAILABLE = 1;
|
||||
public static final int SPI_UNAVAILABLE = 2;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static final String KEY_STATUS = "status";
|
||||
/** @hide */
|
||||
public static final String KEY_RESOURCE_ID = "resourceId";
|
||||
/** @hide */
|
||||
public static final String KEY_SPI = "spi";
|
||||
/** @hide */
|
||||
public static final int INVALID_RESOURCE_ID = 0;
|
||||
|
||||
/**
|
||||
* Indicates that the combination of remote InetAddress and SPI was non-unique for a given
|
||||
* request. If encountered, selection of a new SPI is required before a transform may be
|
||||
@@ -83,22 +109,14 @@ public final class IpSecManager {
|
||||
private final IIpSecService mService;
|
||||
private final InetAddress mRemoteAddress;
|
||||
private final CloseGuard mCloseGuard = CloseGuard.get();
|
||||
private int mSpi;
|
||||
private int mSpi = INVALID_SECURITY_PARAMETER_INDEX;
|
||||
private int mResourceId;
|
||||
|
||||
/** Return the underlying SPI held by this object */
|
||||
public int getSpi() {
|
||||
return mSpi;
|
||||
}
|
||||
|
||||
private SecurityParameterIndex(
|
||||
IIpSecService service, int direction, InetAddress remoteAddress, int spi)
|
||||
throws ResourceUnavailableException, SpiUnavailableException {
|
||||
mService = service;
|
||||
mRemoteAddress = remoteAddress;
|
||||
mSpi = spi;
|
||||
mCloseGuard.open("open");
|
||||
}
|
||||
|
||||
/**
|
||||
* Release an SPI that was previously reserved.
|
||||
*
|
||||
@@ -108,7 +126,7 @@ public final class IpSecManager {
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
mSpi = INVALID_SECURITY_PARAMETER_INDEX; // TODO: Invalid SPI
|
||||
mSpi = INVALID_SECURITY_PARAMETER_INDEX;
|
||||
mCloseGuard.close();
|
||||
}
|
||||
|
||||
@@ -120,14 +138,52 @@ public final class IpSecManager {
|
||||
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Security Parameter Index, SPI, 0 indicates an unknown or invalid index.
|
||||
*
|
||||
* <p>No IPsec packet may contain an SPI of 0.
|
||||
*/
|
||||
public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
|
||||
private SecurityParameterIndex(
|
||||
@NonNull IIpSecService service, int direction, InetAddress remoteAddress, int spi)
|
||||
throws ResourceUnavailableException, SpiUnavailableException {
|
||||
mService = service;
|
||||
mRemoteAddress = remoteAddress;
|
||||
try {
|
||||
Bundle result =
|
||||
mService.reserveSecurityParameterIndex(
|
||||
direction, remoteAddress.getHostAddress(), spi, new Binder());
|
||||
|
||||
if (result == null) {
|
||||
throw new NullPointerException("Received null response from IpSecService");
|
||||
}
|
||||
|
||||
int status = result.getInt(KEY_STATUS);
|
||||
switch (status) {
|
||||
case Status.OK:
|
||||
break;
|
||||
case Status.RESOURCE_UNAVAILABLE:
|
||||
throw new ResourceUnavailableException(
|
||||
"No more SPIs may be allocated by this requester.");
|
||||
case Status.SPI_UNAVAILABLE:
|
||||
throw new SpiUnavailableException("Requested SPI is unavailable", spi);
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Unknown status returned by IpSecService: " + status);
|
||||
}
|
||||
mSpi = result.getInt(KEY_SPI);
|
||||
mResourceId = result.getInt(KEY_RESOURCE_ID);
|
||||
|
||||
if (mSpi == INVALID_SECURITY_PARAMETER_INDEX) {
|
||||
throw new RuntimeException("Invalid SPI returned by IpSecService: " + status);
|
||||
}
|
||||
|
||||
if (mResourceId == INVALID_RESOURCE_ID) {
|
||||
throw new RuntimeException(
|
||||
"Invalid Resource ID returned by IpSecService: " + status);
|
||||
}
|
||||
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
mCloseGuard.open("open");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reserve an SPI for traffic bound towards the specified remote address.
|
||||
@@ -184,7 +240,13 @@ public final class IpSecManager {
|
||||
}
|
||||
|
||||
/* Call down to activate a transform */
|
||||
private void applyTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {}
|
||||
private void applyTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {
|
||||
try {
|
||||
mService.applyTransportModeTransform(pfd, transform.getResourceId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply an active Tunnel Mode IPsec Transform to a network, which will tunnel all traffic to
|
||||
@@ -228,7 +290,13 @@ public final class IpSecManager {
|
||||
}
|
||||
|
||||
/* Call down to activate a transform */
|
||||
private void removeTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {}
|
||||
private void removeTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {
|
||||
try {
|
||||
mService.removeTransportModeTransform(pfd, transform.getResourceId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a Tunnel Mode IPsec Transform from a {@link Network}. This must be used as part of
|
||||
@@ -255,7 +323,7 @@ public final class IpSecManager {
|
||||
private final IIpSecService mService;
|
||||
private final CloseGuard mCloseGuard = CloseGuard.get();
|
||||
|
||||
private UdpEncapsulationSocket(IIpSecService service, int port)
|
||||
private UdpEncapsulationSocket(@NonNull IIpSecService service, int port)
|
||||
throws ResourceUnavailableException {
|
||||
mService = service;
|
||||
mCloseGuard.open("constructor");
|
||||
|
||||
@@ -15,11 +15,21 @@
|
||||
*/
|
||||
package android.net;
|
||||
|
||||
import static android.net.IpSecManager.INVALID_RESOURCE_ID;
|
||||
import static android.net.IpSecManager.KEY_RESOURCE_ID;
|
||||
import static android.net.IpSecManager.KEY_STATUS;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.content.Context;
|
||||
import android.system.ErrnoException;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import dalvik.system.CloseGuard;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -86,39 +96,64 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface EncapType {}
|
||||
|
||||
/**
|
||||
* Sentinel for an invalid transform (means that this transform is inactive).
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int INVALID_TRANSFORM_ID = -1;
|
||||
|
||||
private IpSecTransform(Context context, IpSecConfig config) {
|
||||
mContext = context;
|
||||
mConfig = config;
|
||||
mTransformId = INVALID_TRANSFORM_ID;
|
||||
mResourceId = INVALID_RESOURCE_ID;
|
||||
}
|
||||
|
||||
private IIpSecService getIpSecService() {
|
||||
IBinder b = ServiceManager.getService(android.content.Context.IPSEC_SERVICE);
|
||||
if (b == null) {
|
||||
throw new RemoteException("Failed to connect to IpSecService")
|
||||
.rethrowAsRuntimeException();
|
||||
}
|
||||
|
||||
return IIpSecService.Stub.asInterface(b);
|
||||
}
|
||||
|
||||
private void checkResultStatusAndThrow(int status)
|
||||
throws IOException, IpSecManager.ResourceUnavailableException,
|
||||
IpSecManager.SpiUnavailableException {
|
||||
switch (status) {
|
||||
case IpSecManager.Status.OK:
|
||||
return;
|
||||
// TODO: Pass Error string back from bundle so that errors can be more specific
|
||||
case IpSecManager.Status.RESOURCE_UNAVAILABLE:
|
||||
throw new IpSecManager.ResourceUnavailableException(
|
||||
"Failed to allocate a new IpSecTransform");
|
||||
case IpSecManager.Status.SPI_UNAVAILABLE:
|
||||
Log.wtf(TAG, "Attempting to use an SPI that was somehow not reserved");
|
||||
// Fall through
|
||||
default:
|
||||
throw new IllegalStateException(
|
||||
"Failed to Create a Transform with status code " + status);
|
||||
}
|
||||
}
|
||||
|
||||
private IpSecTransform activate()
|
||||
throws IOException, IpSecManager.ResourceUnavailableException,
|
||||
IpSecManager.SpiUnavailableException {
|
||||
int transformId;
|
||||
synchronized (this) {
|
||||
//try {
|
||||
transformId = INVALID_TRANSFORM_ID;
|
||||
//} catch (RemoteException e) {
|
||||
// throw e.rethrowFromSystemServer();
|
||||
//}
|
||||
try {
|
||||
IIpSecService svc = getIpSecService();
|
||||
Bundle result = svc.createTransportModeTransform(mConfig, new Binder());
|
||||
int status = result.getInt(KEY_STATUS);
|
||||
checkResultStatusAndThrow(status);
|
||||
mResourceId = result.getInt(KEY_RESOURCE_ID, INVALID_RESOURCE_ID);
|
||||
|
||||
if (transformId < 0) {
|
||||
throw new ErrnoException("addTransform", -transformId).rethrowAsIOException();
|
||||
/* Keepalive will silently fail if not needed by the config; but, if needed and
|
||||
* it fails to start, we need to bail because a transform will not be reliable
|
||||
* to use if keepalive is expected to offload and fails.
|
||||
*/
|
||||
// FIXME: if keepalive fails, we need to fail spectacularly
|
||||
startKeepalive(mContext);
|
||||
Log.d(TAG, "Added Transform with Id " + mResourceId);
|
||||
mCloseGuard.open("build");
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowAsRuntimeException();
|
||||
}
|
||||
|
||||
startKeepalive(mContext); // Will silently fail if not required
|
||||
mTransformId = transformId;
|
||||
Log.d(TAG, "Added Transform with Id " + transformId);
|
||||
}
|
||||
mCloseGuard.open("build");
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -133,21 +168,27 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
* transform is no longer needed.
|
||||
*/
|
||||
public void close() {
|
||||
Log.d(TAG, "Removing Transform with Id " + mTransformId);
|
||||
Log.d(TAG, "Removing Transform with Id " + mResourceId);
|
||||
|
||||
// Always safe to attempt cleanup
|
||||
if (mTransformId == INVALID_TRANSFORM_ID) {
|
||||
if (mResourceId == INVALID_RESOURCE_ID) {
|
||||
mCloseGuard.close();
|
||||
return;
|
||||
}
|
||||
//try {
|
||||
stopKeepalive();
|
||||
//} catch (RemoteException e) {
|
||||
// transform.setTransformId(transformId);
|
||||
// throw e.rethrowFromSystemServer();
|
||||
//} finally {
|
||||
mTransformId = INVALID_TRANSFORM_ID;
|
||||
//}
|
||||
mCloseGuard.close();
|
||||
try {
|
||||
/* Order matters here because the keepalive is best-effort but could fail in some
|
||||
* horrible way to be removed if the wifi (or cell) subsystem has crashed, and we
|
||||
* still want to clear out the transform.
|
||||
*/
|
||||
IIpSecService svc = getIpSecService();
|
||||
svc.deleteTransportModeTransform(mResourceId);
|
||||
stopKeepalive();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowAsRuntimeException();
|
||||
} finally {
|
||||
mResourceId = INVALID_RESOURCE_ID;
|
||||
mCloseGuard.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,7 +205,7 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
}
|
||||
|
||||
private final IpSecConfig mConfig;
|
||||
private int mTransformId;
|
||||
private int mResourceId;
|
||||
private final Context mContext;
|
||||
private final CloseGuard mCloseGuard = CloseGuard.get();
|
||||
private ConnectivityManager.PacketKeepalive mKeepalive;
|
||||
@@ -200,6 +241,7 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
|
||||
/* Package */
|
||||
void startKeepalive(Context c) {
|
||||
// FIXME: NO_KEEPALIVE needs to be a constant
|
||||
if (mConfig.getNattKeepaliveInterval() == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -208,7 +250,7 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
(ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
if (mKeepalive != null) {
|
||||
Log.e(TAG, "Keepalive already started for this IpSecTransform.");
|
||||
Log.wtf(TAG, "Keepalive already started for this IpSecTransform.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -218,10 +260,11 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
mConfig.getNetwork(),
|
||||
mConfig.getNattKeepaliveInterval(),
|
||||
mKeepaliveCallback,
|
||||
mConfig.getLocalIp(),
|
||||
mConfig.getLocalAddress(),
|
||||
mConfig.getEncapLocalPort(),
|
||||
mConfig.getRemoteIp());
|
||||
mConfig.getRemoteAddress());
|
||||
try {
|
||||
// FIXME: this is still a horrible way to fudge the synchronous callback
|
||||
mKeepaliveSyncLock.wait(2000);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
@@ -231,6 +274,11 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
/* Package */
|
||||
int getResourceId() {
|
||||
return mResourceId;
|
||||
}
|
||||
|
||||
/* Package */
|
||||
void stopKeepalive() {
|
||||
if (mKeepalive == null) {
|
||||
@@ -247,16 +295,6 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
/* Package */
|
||||
void setTransformId(int transformId) {
|
||||
mTransformId = transformId;
|
||||
}
|
||||
|
||||
/* Package */
|
||||
int getTransformId() {
|
||||
return mTransformId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder object to facilitate the creation of IpSecTransform objects.
|
||||
*
|
||||
@@ -280,7 +318,7 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
*/
|
||||
public IpSecTransform.Builder setEncryption(
|
||||
@TransformDirection int direction, IpSecAlgorithm algo) {
|
||||
mConfig.flow[direction].encryptionAlgo = algo;
|
||||
mConfig.flow[direction].encryption = algo;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -295,7 +333,7 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
*/
|
||||
public IpSecTransform.Builder setAuthentication(
|
||||
@TransformDirection int direction, IpSecAlgorithm algo) {
|
||||
mConfig.flow[direction].authenticationAlgo = algo;
|
||||
mConfig.flow[direction].authentication = algo;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -318,6 +356,8 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
*/
|
||||
public IpSecTransform.Builder setSpi(
|
||||
@TransformDirection int direction, IpSecManager.SecurityParameterIndex spi) {
|
||||
// TODO: convert to using the resource Id of the SPI. Then build() can validate
|
||||
// the owner in the IpSecService
|
||||
mConfig.flow[direction].spi = spi.getSpi();
|
||||
return this;
|
||||
}
|
||||
@@ -439,7 +479,8 @@ public final class IpSecTransform implements AutoCloseable {
|
||||
*
|
||||
* @param context current Context
|
||||
*/
|
||||
public Builder(Context context) {
|
||||
public Builder(@NonNull Context context) {
|
||||
Preconditions.checkNotNull(context);
|
||||
mContext = context;
|
||||
mConfig = new IpSecConfig();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user