Merge "Implement bind-to-network functionality of android.net.Network."
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user