diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl new file mode 100644 index 0000000000..b8737fef72 --- /dev/null +++ b/core/java/android/net/IIpSecService.aidl @@ -0,0 +1,24 @@ +/* +** Copyright 2017, 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 + */ +interface IIpSecService +{ +} diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java index 2c544e9b9b..93a76dfbb4 100644 --- a/core/java/android/net/IpSecManager.java +++ b/core/java/android/net/IpSecManager.java @@ -18,8 +18,6 @@ package android.net; import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.SystemApi; -import android.content.Context; -import android.os.INetworkManagementService; import android.os.ParcelFileDescriptor; import android.util.AndroidException; import dalvik.system.CloseGuard; @@ -79,11 +77,10 @@ public final class IpSecManager { } } - private final Context mContext; - private final INetworkManagementService mService; + private final IIpSecService mService; public static final class SecurityParameterIndex implements AutoCloseable { - private final Context mContext; + private final IIpSecService mService; private final InetAddress mDestinationAddress; private final CloseGuard mCloseGuard = CloseGuard.get(); private int mSpi; @@ -93,9 +90,10 @@ public final class IpSecManager { return mSpi; } - private SecurityParameterIndex(Context context, InetAddress destinationAddress, int spi) + private SecurityParameterIndex( + IIpSecService service, InetAddress destinationAddress, int spi) throws ResourceUnavailableException, SpiUnavailableException { - mContext = context; + mService = service; mDestinationAddress = destinationAddress; mSpi = spi; mCloseGuard.open("open"); @@ -152,7 +150,7 @@ public final class IpSecManager { public SecurityParameterIndex reserveSecurityParameterIndex( InetAddress destinationAddress, int requestedSpi) throws SpiUnavailableException, ResourceUnavailableException { - return new SecurityParameterIndex(mContext, destinationAddress, requestedSpi); + return new SecurityParameterIndex(mService, destinationAddress, requestedSpi); } /** @@ -260,19 +258,19 @@ public final class IpSecManager { */ public static final class UdpEncapsulationSocket implements AutoCloseable { private final FileDescriptor mFd; - private final Context mContext; + private final IIpSecService mService; private final CloseGuard mCloseGuard = CloseGuard.get(); - private UdpEncapsulationSocket(Context context, int port) + private UdpEncapsulationSocket(IIpSecService service, int port) throws ResourceUnavailableException { - mContext = context; + mService = service; mCloseGuard.open("constructor"); // TODO: go down to the kernel and get a socket on the specified mFd = new FileDescriptor(); } - private UdpEncapsulationSocket(Context context) throws ResourceUnavailableException { - mContext = context; + private UdpEncapsulationSocket(IIpSecService service) throws ResourceUnavailableException { + mService = service; mCloseGuard.open("constructor"); // TODO: go get a random socket on a random port mFd = new FileDescriptor(); @@ -339,7 +337,7 @@ public final class IpSecManager { public UdpEncapsulationSocket openUdpEncapsulationSocket(int port) throws IOException, ResourceUnavailableException { // Temporary code - return new UdpEncapsulationSocket(mContext, port); + return new UdpEncapsulationSocket(mService, port); } /** @@ -363,7 +361,7 @@ public final class IpSecManager { public UdpEncapsulationSocket openUdpEncapsulationSocket() throws IOException, ResourceUnavailableException { // Temporary code - return new UdpEncapsulationSocket(mContext); + return new UdpEncapsulationSocket(mService); } /** @@ -372,8 +370,7 @@ public final class IpSecManager { * @param context the application context for this manager * @hide */ - public IpSecManager(Context context, INetworkManagementService service) { - mContext = checkNotNull(context, "missing context"); + public IpSecManager(IIpSecService service) { mService = checkNotNull(service, "missing service"); } } diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java new file mode 100644 index 0000000000..994adc480f --- /dev/null +++ b/services/core/java/com/android/server/IpSecService.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2017 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 com.android.server; + +import static android.Manifest.permission.DUMP; + +import android.content.Context; +import android.net.IIpSecService; +import android.net.INetd; +import android.net.util.NetdService; +import android.os.RemoteException; +import android.util.Log; +import android.util.Slog; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** @hide */ +public class IpSecService extends IIpSecService.Stub { + private static final String TAG = "IpSecService"; + private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); + private static final String NETD_SERVICE_NAME = "netd"; + + /** Binder context for this service */ + private final Context mContext; + + private Object mLock = new Object(); + + private static final int NETD_FETCH_TIMEOUT = 5000; //ms + + /** + * Constructs a new IpSecService instance + * + * @param context Binder context for this service + */ + private IpSecService(Context context) { + mContext = context; + } + + static IpSecService create(Context context) throws InterruptedException { + final IpSecService service = new IpSecService(context); + service.connectNativeNetdService(); + return service; + } + + public void systemReady() { + if (isNetdAlive()) { + Slog.d(TAG, "IpSecService is ready"); + } else { + Slog.wtf(TAG, "IpSecService not ready: failed to connect to NetD Native Service!"); + } + } + + private void connectNativeNetdService() { + // Avoid blocking the system server to do this + Thread t = + new Thread( + new Runnable() { + @Override + public void run() { + synchronized (mLock) { + NetdService.get(NETD_FETCH_TIMEOUT); + } + } + }); + t.run(); + } + + INetd getNetdInstance() { + final INetd netd = NetdService.getInstance(); + if (netd == null) { + throw new RemoteException("Failed to Get Netd Instance").rethrowFromSystemServer(); + } + return netd; + } + + boolean isNetdAlive() { + synchronized (mLock) { + final INetd netd = getNetdInstance(); + if (netd == null) { + return false; + } + + try { + return netd.isAlive(); + } catch (RemoteException re) { + return false; + } + } + } + + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + mContext.enforceCallingOrSelfPermission(DUMP, TAG); + + pw.println("IpSecService Log:"); + pw.println("NetdNativeService Connection: " + (isNetdAlive() ? "alive" : "dead")); + pw.println(); + } +}