Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d6f265d authored by Paul Jensen's avatar Paul Jensen Committed by Robert Greenwalt
Browse files

Implement bind-to-network functionality of android.net.Network.

This is implemented by calling through to netd_client.
Included are functions to bind-to-network-for-process strictly for DNS to
facilitate startUsingNetworkFeature() reimplementation.

bug: 13885501

Change-Id: Ib22c7d02ea81d251bdfeeb0f64a47ce32eefcb1b
(cherry picked from commit dbf76f898f1f57eb74722358087c926d2f529bda)
parent c7b1b7ae
Loading
Loading
Loading
Loading
+87 −2
Original line number Original line Diff line number Diff line
@@ -16,10 +16,13 @@


package android.net;
package android.net;


import android.net.NetworkUtils;
import android.os.Parcelable;
import android.os.Parcelable;
import android.os.Parcel;
import android.os.Parcel;


import java.io.IOException;
import java.net.InetAddress;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
import javax.net.SocketFactory;
@@ -38,6 +41,8 @@ public class Network implements Parcelable {
     */
     */
    public final int netId;
    public final int netId;


    private NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;

    /**
    /**
     * @hide
     * @hide
     */
     */
@@ -78,6 +83,59 @@ public class Network implements Parcelable {
        return InetAddress.getByNameOnNet(host, netId);
        return InetAddress.getByNameOnNet(host, netId);
    }
    }


    /**
     * A {@code SocketFactory} that produces {@code Socket}'s bound to this network.
     */
    private class NetworkBoundSocketFactory extends SocketFactory {
        private final int mNetId;

        public NetworkBoundSocketFactory(int netId) {
            super();
            mNetId = netId;
        }

        @Override
        public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
            Socket socket = createSocket();
            socket.bind(new InetSocketAddress(localHost, localPort));
            socket.connect(new InetSocketAddress(host, port));
            return socket;
        }

        @Override
        public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
                int localPort) throws IOException {
            Socket socket = createSocket();
            socket.bind(new InetSocketAddress(localAddress, localPort));
            socket.connect(new InetSocketAddress(address, port));
            return socket;
        }

        @Override
        public Socket createSocket(InetAddress host, int port) throws IOException {
            Socket socket = createSocket();
            socket.connect(new InetSocketAddress(host, port));
            return socket;
        }

        @Override
        public Socket createSocket(String host, int port) throws IOException {
            Socket socket = createSocket();
            socket.connect(new InetSocketAddress(host, port));
            return socket;
        }

        @Override
        public Socket createSocket() throws IOException {
            Socket socket = new Socket();
            // Query a property of the underlying socket to ensure the underlying
            // socket exists so a file descriptor is available to bind to a network.
            socket.getReuseAddress();
            NetworkUtils.bindSocketToNetwork(socket.getFileDescriptor$().getInt$(), mNetId);
            return socket;
        }
    }

    /**
    /**
     * Returns a {@link SocketFactory} bound to this network.  Any {@link Socket} created by
     * Returns a {@link SocketFactory} bound to this network.  Any {@link Socket} created by
     * this factory will have its traffic sent over this {@code Network}.  Note that if this
     * this factory will have its traffic sent over this {@code Network}.  Note that if this
@@ -88,7 +146,10 @@ public class Network implements Parcelable {
     *         {@code Network}.
     *         {@code Network}.
     */
     */
    public SocketFactory socketFactory() {
    public SocketFactory socketFactory() {
        return null;
        if (mNetworkBoundSocketFactory == null) {
            mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(netId);
        }
        return mNetworkBoundSocketFactory;
    }
    }


    /**
    /**
@@ -99,6 +160,29 @@ public class Network implements Parcelable {
     * doesn't accidentally use sockets it thinks are still bound to a particular {@code Network}.
     * doesn't accidentally use sockets it thinks are still bound to a particular {@code Network}.
     */
     */
    public void bindProcess() {
    public void bindProcess() {
        NetworkUtils.bindProcessToNetwork(netId);
    }

    /**
     * Binds host resolutions performed by this process to this network.  {@link #bindProcess}
     * takes precedence over this setting.
     *
     * @hide
     * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
     */
    public void bindProcessForHostResolution() {
        NetworkUtils.bindProcessToNetworkForHostResolution(netId);
    }

    /**
     * Clears any process specific {@link Network} binding for host resolution.  This does
     * not clear bindings enacted via {@link #bindProcess}.
     *
     * @hide
     * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
     */
    public void unbindProcessForHostResolution() {
        NetworkUtils.unbindProcessToNetworkForHostResolution();
    }
    }


    /**
    /**
@@ -107,7 +191,7 @@ public class Network implements Parcelable {
     * @return {@code Network} to which this process is bound.
     * @return {@code Network} to which this process is bound.
     */
     */
    public static Network getProcessBoundNetwork() {
    public static Network getProcessBoundNetwork() {
        return null;
        return new Network(NetworkUtils.getNetworkBoundToProcess());
    }
    }


    /**
    /**
@@ -115,6 +199,7 @@ public class Network implements Parcelable {
     * {@link Network#bindProcess}.
     * {@link Network#bindProcess}.
     */
     */
    public static void unbindProcess() {
    public static void unbindProcess() {
        NetworkUtils.unbindProcessToNetwork();
    }
    }


    // implement the Parcelable interface
    // implement the Parcelable interface
+44 −0
Original line number Original line Diff line number Diff line
@@ -108,6 +108,50 @@ public class NetworkUtils {
     */
     */
    public native static void markSocket(int socketfd, int mark);
    public native static void markSocket(int socketfd, int mark);


    /**
     * Binds the current process to the network designated by {@code netId}.  All sockets created
     * in the future (and not explicitly bound via a bound {@link SocketFactory} (see
     * {@link Network#socketFactory}) will be bound to this network.  Note that if this
     * {@code Network} ever disconnects all sockets created in this way will cease to work.  This
     * is by design so an application doesn't accidentally use sockets it thinks are still bound to
     * a particular {@code Network}.
     */
    public native static void bindProcessToNetwork(int netId);

    /**
     * Clear any process specific {@code Network} binding.  This reverts a call to
     * {@link #bindProcessToNetwork}.
     */
    public native static void unbindProcessToNetwork();

    /**
     * Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if
     * {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}.
     */
    public native static int getNetworkBoundToProcess();

    /**
     * Binds host resolutions performed by this process to the network designated by {@code netId}.
     * {@link #bindProcessToNetwork} takes precedence over this setting.
     *
     * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
     */
    public native static void bindProcessToNetworkForHostResolution(int netId);

    /**
     * Clears any process specific {@link Network} binding for host resolution.  This does
     * not clear bindings enacted via {@link #bindProcessToNetwork}.
     *
     * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
     */
    public native static void unbindProcessToNetworkForHostResolution();

    /**
     * Explicitly binds {@code socketfd} to the network designated by {@code netId}.  This
     * overrides any binding via {@link #bindProcessToNetwork}.
     */
    public native static void bindSocketToNetwork(int socketfd, int netId);

    /**
    /**
     * Convert a IPv4 address from an integer to an InetAddress.
     * Convert a IPv4 address from an integer to an InetAddress.
     * @param hostAddress an int corresponding to the IPv4 address in network byte order
     * @param hostAddress an int corresponding to the IPv4 address in network byte order
+3 −0
Original line number Original line Diff line number Diff line
@@ -173,8 +173,10 @@ LOCAL_C_INCLUDES += \
	$(call include-path-for, bluedroid) \
	$(call include-path-for, bluedroid) \
	$(call include-path-for, libhardware)/hardware \
	$(call include-path-for, libhardware)/hardware \
	$(call include-path-for, libhardware_legacy)/hardware_legacy \
	$(call include-path-for, libhardware_legacy)/hardware_legacy \
	$(TOP)/bionic/libc/dns/include \
	$(TOP)/frameworks/av/include \
	$(TOP)/frameworks/av/include \
	$(TOP)/system/media/camera/include \
	$(TOP)/system/media/camera/include \
	$(TOP)/system/netd/include \
	external/pdfium/core/include/fpdfapi \
	external/pdfium/core/include/fpdfapi \
	external/pdfium/core/include/fpdfdoc \
	external/pdfium/core/include/fpdfdoc \
	external/pdfium/fpdfsdk/include \
	external/pdfium/fpdfsdk/include \
@@ -233,6 +235,7 @@ LOCAL_SHARED_LIBRARIES := \
	libaudioutils \
	libaudioutils \
	libpdfium \
	libpdfium \
	libimg_utils \
	libimg_utils \
	libnetd_client \


ifeq ($(USE_OPENGL_RENDERER),true)
ifeq ($(USE_OPENGL_RENDERER),true)
	LOCAL_SHARED_LIBRARIES += libhwui
	LOCAL_SHARED_LIBRARIES += libhwui
+38 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@


#include "jni.h"
#include "jni.h"
#include "JNIHelp.h"
#include "JNIHelp.h"
#include "NetdClient.h"
#include "resolv_netid.h"
#include <utils/misc.h>
#include <utils/misc.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
#include <utils/Log.h>
@@ -250,6 +252,36 @@ static void android_net_utils_markSocket(JNIEnv *env, jobject thiz, jint socket,
    }
    }
}
}


static void android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
{
    setNetworkForProcess(netId);
}

static void android_net_utils_unbindProcessToNetwork(JNIEnv *env, jobject thiz)
{
    setNetworkForProcess(NETID_UNSET);
}

static jint android_net_utils_getNetworkBoundToProcess(JNIEnv *env, jobject thiz)
{
    return getNetworkForProcess();
}

static void android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz, jint netId)
{
    setNetworkForResolv(netId);
}

static void android_net_utils_unbindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz)
{
    setNetworkForResolv(NETID_UNSET);
}

static void android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, jint socket, jint netId)
{
    setNetworkForSocket(netId, socket);
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


/*
/*
@@ -267,6 +299,12 @@ static JNINativeMethod gNetworkUtilMethods[] = {
    { "releaseDhcpLease", "(Ljava/lang/String;)Z",  (void *)android_net_utils_releaseDhcpLease },
    { "releaseDhcpLease", "(Ljava/lang/String;)Z",  (void *)android_net_utils_releaseDhcpLease },
    { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
    { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
    { "markSocket", "(II)V", (void*) android_net_utils_markSocket },
    { "markSocket", "(II)V", (void*) android_net_utils_markSocket },
    { "bindProcessToNetwork", "(I)V", (void*) android_net_utils_bindProcessToNetwork },
    { "getNetworkBoundToProcess", "()I", (void*) android_net_utils_getNetworkBoundToProcess },
    { "unbindProcessToNetwork", "()V", (void*) android_net_utils_unbindProcessToNetwork },
    { "bindProcessToNetworkForHostResolution", "(I)V", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
    { "unbindProcessToNetworkForHostResolution", "()V", (void*) android_net_utils_unbindProcessToNetworkForHostResolution },
    { "bindSocketToNetwork", "(II)V", (void*) android_net_utils_bindSocketToNetwork },
};
};


int register_android_net_NetworkUtils(JNIEnv* env)
int register_android_net_NetworkUtils(JNIEnv* env)