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

Commit 104b0f13 authored by Erik Kline's avatar Erik Kline
Browse files

multinetwork API: native implementation

Bug: 19537384
Change-Id: I04f4a7de2b1e583989b67a853df6ab50289c2185
parent de93575d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -17153,6 +17153,7 @@ package android.net {
    method public int describeContents();
    method public java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException;
    method public java.net.InetAddress getByName(java.lang.String) throws java.net.UnknownHostException;
    method public long getNetworkHandle();
    method public javax.net.SocketFactory getSocketFactory();
    method public java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
    method public java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException;
+1 −0
Original line number Diff line number Diff line
@@ -18414,6 +18414,7 @@ package android.net {
    method public int describeContents();
    method public java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException;
    method public java.net.InetAddress getByName(java.lang.String) throws java.net.UnknownHostException;
    method public long getNetworkHandle();
    method public javax.net.SocketFactory getSocketFactory();
    method public java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
    method public java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException;
+29 −0
Original line number Diff line number Diff line
@@ -340,6 +340,35 @@ public class Network implements Parcelable {
        }
    }

    /**
     * Returns a handle representing this {@code Network}, for use with the NDK API.
     */
    public long getNetworkHandle() {
        // The network handle is explicitly not the same as the netId.
        //
        // The netId is an implementation detail which might be changed in the
        // future, or which alone (i.e. in the absence of some additional
        // context) might not be sufficient to fully identify a Network.
        //
        // As such, the intention is to prevent accidental misuse of the API
        // that might result if a developer assumed that handles and netIds
        // were identical and passing a netId to a call expecting a handle
        // "just worked".  Such accidental misuse, if widely deployed, might
        // prevent future changes to the semantics of the netId field or
        // inhibit the expansion of state required for Network objects.
        //
        // This extra layer of indirection might be seen as paranoia, and might
        // never end up being necessary, but the added complexity is trivial.
        // At some future date it may be desirable to realign the handle with
        // Multiple Provisioning Domains API recommendations, as made by the
        // IETF mif working group.
        //
        // The HANDLE_MAGIC value MUST be kept in sync with the corresponding
        // value in the native/android/net.c NDK implementation.
        final long HANDLE_MAGIC = 0xfacade;
        return (((long) netId) << 32) | HANDLE_MAGIC;
    }

    // implement the Parcelable interface
    public int describeContents() {
        return 0;
+7 −3
Original line number Diff line number Diff line
@@ -12,9 +12,10 @@ LOCAL_SRC_FILES:= \
    looper.cpp \
    native_activity.cpp \
    native_window.cpp \
    net.c \
    obb.cpp \
    sensor.cpp \
    storage_manager.cpp
    storage_manager.cpp \

LOCAL_SHARED_LIBRARIES := \
    liblog \
@@ -25,14 +26,17 @@ LOCAL_SHARED_LIBRARIES := \
    libbinder \
    libui \
    libgui \
    libandroid_runtime
    libandroid_runtime \
    libnetd_client \

LOCAL_STATIC_LIBRARIES := \
    libstorage

LOCAL_C_INCLUDES += \
    frameworks/base/native/include \
    frameworks/base/core/jni/android
    frameworks/base/core/jni/android \
    bionic/libc/dns/include \
    system/netd/include \

LOCAL_MODULE:= libandroid

native/android/net.c

0 → 100644
+85 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.
 */


#include <android/multinetwork.h>
#include <errno.h>
#include <NetdClient.h>    // the functions that communicate with netd
#include <resolv_netid.h>  // android_getaddrinfofornet()
#include <stdlib.h>
#include <sys/limits.h>


static int getnetidfromhandle(net_handle_t handle, unsigned *netid) {
    static const uint32_t k32BitMask = 0xffffffff;
    // This value MUST be kept in sync with the corresponding value in
    // the android.net.Network#getNetworkHandle() implementation.
    static const uint32_t kHandleMagic = 0xfacade;

    // Check for minimum acceptable version of the API in the low bits.
    if (handle != NETWORK_UNSPECIFIED &&
        (handle & k32BitMask) != kHandleMagic) {
        return 0;
    }

    if (netid != NULL) {
        *netid = ((handle >> (CHAR_BIT * sizeof(k32BitMask))) & k32BitMask);
    }
    return 1;
}


int android_setsocknetwork(net_handle_t network, int fd) {
    unsigned netid;
    if (!getnetidfromhandle(network, &netid)) {
        errno = EINVAL;
        return -1;
    }

    int rval = setNetworkForSocket(netid, fd);
    if (rval < 0) {
        errno = -rval;
        rval = -1;
    }
    return rval;
}

int android_setprocnetwork(net_handle_t network) {
    unsigned netid;
    if (!getnetidfromhandle(network, &netid)) {
        errno = EINVAL;
        return -1;
    }

    int rval = setNetworkForProcess(netid);
    if (rval < 0) {
        errno = -rval;
        rval = -1;
    }
    return rval;
}

int android_getaddrinfofornetwork(net_handle_t network,
        const char *node, const char *service,
        const struct addrinfo *hints, struct addrinfo **res) {
    unsigned netid;
    if (!getnetidfromhandle(network, &netid)) {
        errno = EINVAL;
        return EAI_SYSTEM;
    }

    return android_getaddrinfofornet(node, service, hints, netid, 0, res);
}